Boot

EFI文件路徑後的’efibootmgr -v’是什麼意思

  • December 6, 2021

當我執行efibootmgr列出所有啟動選項時,輸出如下:

$ efibootmgr
BootCurrent: 0003
Timeout: 1 seconds
BootOrder: 0000,0002,0003,0001
Boot0000* (my linux distro grub boot)
Boot0001* file
Boot0002* Windows Boot Manager
Boot0003* (my linux distro systemd-boot)

當我想查看更詳細的輸出時,我得到了這個:

$ efibootmgr -v
BootCurrent: 0003
Timeout: 1 seconds
BootOrder: 0000,0002,0003,0001
Boot0000* (my linux distro grub boot)       HD(1,GPT,3e1eXXXX-f3XX-40XX-b1XX-569aXXXXXXXX,0x800,0x82000)/File(\EFI\DISTRONAME-GRUB\GRUBX64.EFI)
Boot0001* file  VenHw(99e2XXXX-75XX-4bXX-a2XX-c538XXXXXXXX)
Boot0002* Windows Boot Manager  HD(1,GPT,3e1eXXXX-f3XX-40XX-b1XX-569aXXXXXXXX,0x800,0x82000)/File(\EFI\MICROSOFT\BOOT\BOOTMGFW.EFI)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.X.X.X.X.-.5.c.X.X.-.4.e.X.X.-.a.c.X.X.-.f.3.2.b.X.X.X.X.X.X.X.X.}....................
Boot0003* (my linux distro systemd-boot)    HD(1,GPT,3e1eXXXX-f3XX-40XX-b1XX-569aXXXX,0x800,0x82000)/File(\EFI\DISTRONAME-SYSTEMDBOOT\systemd-bootx64.efi)

根據我在手冊頁(https://linux.die.net/man/8/efibootmgr)中的推理和快速搜尋,輸出的格式為:

BootNNNNA NAME WHATTOBOOT

在哪裡:

NNNN = boot number (0000 until maybe 9999)
A = * if active, no asterisk if not active
NAME = string label that will be shown on vendor/motherboard BIOS (UEFI)
WHATTOBOOT = can be
 - HD({NUMBER},{GPT/MBR},{UUID-from-blkid-PARTUUID})/File({\PATH\TO\EFI})
 - PXE ((I have no such boot option in this PC))

現在我很好奇的是efibootmgr -v輸出的含義,Windows boot manager它顯示為:

Boot0002* Windows Boot Manager  HD(1,GPT,3e1eXXXX-f3XX-40XX-b1XX-569aXXXXXXXX,0x800,0x82000)/File(\EFI\MICROSOFT\BOOT\BOOTMGFW.EFI)WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.X.X.X.X.-.5.c.X.X.-.4.e.X.X.-.a.c.X.X.-.f.3.2.b.X.X.X.X.X.X.X.X.}....................
  • 基於它的 PARTUUID,它位於我的 EFI 分區上(與我的其他引導選項相同)
  • 然後它的 EFI 文件位於 \EFI\MICROSOFT\BOOT\BOOTMGFW.EFI
  • 最後,後面有一個字元串(或者可能是二進制):
WINDOWS.........x...B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.X.X.X.X.-.5.c.X.X.-.4.e.X.X.-.a.c.X.X.-.f.3.2.b.X.X.X.X.X.X.X.X.}....................

我要問的是:這個字元串是什麼意思?如果我刪除之間的所有點 (.) 字元(這將使它成為xBCOBJECT=9deaXXXX-5cXX-4eXX-acXX-f32bXXXXXXXX

我也很好奇第二個引導選項是什麼意思:Boot0001* file或詳細版本Boot0001* file VenHw(99e2XXXX-75XX-4bXX-a2XX-c538XXXXXXXX)

  • 我懷疑這是我幾年前忘記刪除的快閃記憶體驅動器/拇指驅動器啟動,這是正確的嗎?或者是別的什麼?

附加資訊:

版本:

$ efibootmgr --version
version 17

我的設置:Windows+linux 雙啟動,在 linux 上我安裝了這些啟動管理器:grub 和 systemd-boot

TL;博士:

傳遞給載入圖像的二進制數據緩衝區。

搜尋過程的詳細描述

efibootmgr 源包含一個輸出 EFI 引導變數的函式(文件 efibootmgr.c):

 static void
 show_vars(const char *prefix)
 {
         list_t *pos;
         var_entry_t *boot;
         const unsigned char *description;
         efi_load_option *load_option;

         list_for_each(pos, &entry_list) {
                 boot = list_entry(pos, var_entry_t, list);
                 load_option = (efi_load_option *)boot->data;
                 description = efi_loadopt_desc(load_option, boot->data_size);
                 if (boot->name)
                         printf("%s", boot->name);
                 else
                         printf("%s%04X", prefix, boot->num);

                 printf("%c ", (efi_loadopt_attrs(load_option)
                         ⁞      & LOAD_OPTION_ACTIVE) ? '*' : ' ');
                 printf("%s", description);

                 show_var_path(load_option, boot->data_size);

                 fflush(stdout);
         }
 }

有趣的是這條線

description = efi_loadopt_desc(load_option, boot->data_size);

所以,我們需要找到一個函式efi_loadopt_desc。它不包含在 efibootmgr 本身中。在 /usr/include 中搜尋包含文件會給出:

$ grep -ri efi_loadopt_desc /usr/include
/usr/include/efivar/efiboot-loadopt.h:extern const unsigned char * efi_loadopt_desc(efi_load_option *opt,

如果我們查看文件 /usr/include/efivar/efiboot-loadopt.h 中的狀態:

/*
* libefiboot - library for the manipulation of EFI boot variables
* Copyright 2012-2015 Red Hat, Inc.
* Copyright (C) 2001 Dell Computer Corporation <Matt_Domsch@dell.com>
*
...
*/

進一步調查導致efivar 儲存庫,其中包含efi_loadopt_desc文件 src/loadopt.c 中的函式。在那裡它只是返回opt->descriptiona 的欄位struct efi_load_option_s

last_desc = ucs2_to_utf8(opt->description, limit);

該結構被定義為

typedef struct efi_load_option_s {
       uint32_t attributes;
       uint16_t file_path_list_length;
       uint16_t description[];
       // uint8_t file_path_list[];
       // uint8_t optional_data[];
} PACKED efi_load_option;

因此,在載入選項文件路徑之後得到輸出的部分稱為“可選數據”。進一步調查導致文件src/efivarfs.c和函式efivarfs_get_variable,這表明它讀取了 efivarfs(EFI var 文件系統),該文件通常位於 /sys/firmware/efi/efivarfs 下,並暴露了許多虛擬“文件”。名稱以開頭的文件Boot000包含有關引導選項的資訊,以及其他數據,這些“可選數據”描述了特定的引導條目。似乎只有在引導名稱、引導條目文件路徑和“可選數據”的組合資訊不超過opt_size.

更多資訊:

https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface#Services

變數服務

UEFI 變數提供了一種儲存數據的方式,尤其是非易失性數據。一些 UEFI 變數在平台韌體和作業系統之間共享。變數命名空間由 GUID 標識,變數是鍵/值對。例如,UEFI 變數可用於在崩潰後將崩潰消息保存在 NVRAM 中,以便作業系統在重新啟動後檢索。

$$ 45 $$

https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface#UEFI_booting

引導配置由儲存在 NVRAM 中的變數定義,包括指示 OS 載入程序或 OS 核心的文件系統路徑的變數。

注意: UEFI 規範對“可選數據”有這樣的說法:

https://uefi.org/specifications

https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf (第 72 頁)

OptionalData

載入選項描述符中剩餘的字節是傳遞給載入圖像的二進制數據緩衝區。如果該欄位的長度為零字節,則將 NULL 指針傳遞給載入的圖像。OptionalData 中的字節數可以通過從 EFI_LOAD_OPTION 的總大小(以字節為單位)中減去 OptionalData 的起始偏移量來計算。

引用自:https://unix.stackexchange.com/questions/666459