UEFI 何时以及为何需要访问分区表?

UEFI 何时以及为何需要访问分区表?

我有一个带有固件的工作站和带有类型分区表的UEFI磁盘。GPT根据 EFI Boot Manager,系统被指示从 UUID 启动7e169454-1df0-40bf-9c63-0f6b094c1e15

# efibootmgr -v
BootCurrent: 0000
Timeout: 1 seconds
BootOrder: 0000
Boot0000* debian        HD(1,GPT,7e169454-1df0-40bf-9c63-0f6b094c1e15,0x800,0xee000)/File(\EFI\debian\grubx64.efi)
#

7e169454-1df0-40bf-9c63-0f6b094c1e15/dev/sdb是带有FAT32文件系统的磁盘的第一个分区:

# blkid /dev/sdb1
/dev/sdb1: UUID="DA79-BCEA" TYPE="vfat" PARTUUID="7e169454-1df0-40bf-9c63-0f6b094c1e15"
#

根据本 UEFI 指南,UEFI 规范要求 UEFI 能够读取 ( GPT) 分区表。仅在安装/编辑 EFI 启动管理器期间才需要此操作吗?据我了解,会将efibootmgr分区的起始扇区和结束扇区添加到 EFI 启动管理器条目中。例如,根据上面的示例,我的 EFI 启动管理器条目包含0x800(2048以十进制表示) 和0xee000(以十进制表示) ,它们与从以下位置读取的974848开始和结束扇区相匹配:fdiskGPT

# fdisk /dev/sdb

Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): i
Partition number (1-4, default 4): 1

         Device: /dev/sdb1
          Start: 2048
            End: 976895
        Sectors: 974848
           Size: 476M
           Type: EFI System
      Type-UUID: C12A7328-F81F-11D2-BA4B-00A0C93EC93B
           UUID: 7E169454-1DF0-40BF-9C63-0F6B094C1E15

是否UEFI需要访问分区表才能使用起始和结束扇区信息填充 EFI 启动管理器?

或者可能UEFI需要在每次启动期间访问分区表,因为它需要找到与UUID?匹配的分区。如果我明白的话UEFI指南正确的话,那么在启动过程中UEFI将以不特定的顺序初始化每个外围设备,直到找到与该UUID.因此,在我的示例中,它会从 EFI 启动管理器读取7e169454-1df0-40bf-9c63-0f6b094c1e15,然后遍历每个块设备并读取其 GPT,直到7e169454-1df0-40bf-9c63-0f6b094c1e15找到分区?

答案1

根据此 UEFI 指南,UEFI 规范要求 UEFI 能够读取 (GPT) 分区表。

这是一个规范要求,因此这意味着虽然特定的 UEFI 固件实现可能也支持其他分区表格式,每一个UEFI实施必须还支持 GPT 以符合规范。因此,PC 硬件上的 UEFI 实现通常也会支持经典的 MBR 分区,至少足以识别它。 Apple 的 UEFI 实现也可能支持 Apple 自己的旧分区方案,Oracle/Sun UEFI 也可能理解 Solaris VTOC 磁盘标签,等等。

仅在安装/编辑 EFI 启动管理器期间才需要此操作吗?

EFI 启动管理器内置于 UEFI 固件中。你永远不会“安装”它。使用该efibootmgr命令,您可以编辑其参数它们存储在主板上的非易失性存储器 (NVRAM) 中。

UEFI 固件需要能够在每次启动时读取 GPT 分区表,除非系统是使用特定 UEFI 实现支持的替代分区表格式安装的。

HD(1,GPT,7e169454-1df0-40bf-9c63-0f6b094c1e15,0x800,0xee000)输出中的字符串efibootmgr不仅仅是任何字符串:它是人类可读的简明表示形式UEFI硬盘媒体设备路径数据结构。该数据结构是数据实际存储在 EFI 启动管理器的 NVRAM 中的方式。

UEFI规范说(我强调并分成几段):

启动管理器还必须支持从短格式设备路径启动,该路径以第一个元素开始硬盘媒体设备路径(见表77)。引导管理器必须使用硬盘驱动器设备路径中的 GUID 或签名和分区号,以将其与系统中的设备相匹配。

如果驱动器支持 GPT 分区方案,则 GUID 位于硬盘媒体设备路径UniquePartitionGuid与GUID 分区条目的字段进行比较(参见表 18)。如果驱动器支持 PC-AT MBR 方案,则签名中硬盘媒体设备路径UniqueMBRSignature与传统主引导记录中的进行比较(参见表 13)。

如果签名匹配,则分区号也必须匹配。硬盘驱动器设备路径可以附加到匹配的硬件设备路径,然后可以使用正常的引导行为。如果有多个设备与硬盘设备路径匹配,引导管理器将任意选择一个。因此,操作系统必须确保硬盘驱动器上签名的唯一性,以保证确定性的引导行为。

因此通过分区的唯一UUID进行匹配是主要机制。起始和结束扇区信息只是为了提供冗余:任何 UEFI 实现都可以自由地使用它或忽略它。

UEFI 固件可能会使用起始和结束扇区信息来进一步检查 NVRAM 信息和磁盘内容是否相互匹配。如果磁盘的分区表似乎已损坏,它还允许固件尝试按位置查找 ESP 分区,从而使系统能够更可靠地防止数据错误。每个 UEFI 固件实施者都可以自行决定是否要使用这些额外信息,如果需要,他们的总体策略是什么。

考虑到安全性的 UEFI 实现可能会停止启动过程并报告任何差异的错误,而设计为最大可靠性的实现可能会在失败之前尝试冗余信息的所有组合,以最大限度地解决单个错误的机会NVRAM 或分区表。如果未能找到匹配的签名,极简 UEFI 实现可能会停止并显示错误消息,并完全忽略额外信息。

如果您想更好地了解 UEFI 及其功能,您应该尝试使用 UEFI shell。一些 UEFI 实现(例如 Intel 或 Phoenix)将其内置;其他(由 AMI)shellx64.efi如果将文件添加到 ESP(EFI 系统分区)的根目录,则有一个特定的选项来运行文件。如果所有其他方法都失败,您始终可以将.efishell 文件放置到 ESP 上,并将efibootmgr其配置为 EFI Boot Manager 中的附加启动菜单项。

在撰写本文时,TianoCore 项目提供的 UEFI shell 的最新预编译版本似乎位于: https://github.com/tianocore/edk2/releases/download/edk2-stable201911/ShellBinPkg.zip

相关内容