GRUB2 UEFI 加载程序如何知道在哪里寻找配置文件(或第二阶段的文件所在的位置)?

How does the GRUB2 UEFI loader know where to look for the configuration file (or where the 2nd stage's files are located)?

如果我在启用 GPT 的分区上使用 GRUB2,加载程序如何 "know" 在哪里可以找到它的配置文件和其他第二阶段的文件?

注意:我发现一些关于配置文件的提及,该配置文件位于与 GRUB 的 EFI 加载程序相同的文件夹中,并且包含来自指定分区的 "primary" 配置文件的链式加载,但这绝对不是真的 -只有一个 "something.efi" 个文件。

实际有几种可能发生这种情况:

  • 加载嵌入式配置文件。
  • 在与 GRUB 二进制文件相同的目录中加载配置文件。
  • grub-mkimage(由 grub-install 调用)执行时间确定的路径加载配置文件。

后者可能是您真正需要的功能 - 它是默认配置文件名 (grub.cfg)、前缀(默认 /boot/grub,但可以显式指定为grub-mkimage)和前缀所在分区的grub分区名

如果我 运行 strings /boot/efi/EFI/debian/grubx64.efi | tail -1 在我当前的工作站上,它会打印出存储的值:(,gpt2)/boot/grub,告诉 grubx64.efi 在 [= 中查找它的配置文件38=] 在 GPT 分区 2 上。逗号前的位(GRUB 磁盘设备名称)在 运行 时间根据 grubx64.efi 映像本身从哪个磁盘加载。

还将在此位置下搜索动态加载的模块,但在 architecture/platform-specific 目录中 - 在本例中为 /boot/grub/x86_64-efi.

对于 EFI 映像,我发现 grub-installgrub-mkimage 总是 early config 嵌入到结果 EFI 二进制文件中,无论您是否指定了 --config FILE 选项。如果不指定 --config FILE 选项,它将尝试嵌入 /boot/grub/x86-64_efi/load.cfg, 这个早期的配置文件如下所示:

    search.fs_uuid 8ef704aa-041d-443c-8ce6-71ac7e7f30da root hd0,gpt1
    set prefix=($root)'/boot/grub'
    configfile $prefix/grub.cfg  # this line seems can be omitted, because it seems to be the default next action
  • uuid是文件系统的uuid,不是分区的uuid,可以用blkid列出。
  • hd0,gpt1 只是一个提示。
  • 你可以把第一行改成set root=hd0,gpt1

这种自动嵌入的默认行为与 BIOS 模式不同,后者默认只嵌入像 (,gpt3)/boot 这样的前缀字符串而不会打扰 search.uuid.

我还发现 Ubuntu 仿生 EFI 图像嵌入了这样的早期配置 https://source.puri.sm/pureos/core/grub2/blob/master/debian/build-efi-images#L64

if [ -z "$prefix" -o ! -e "$prefix" ]; then
    if ! search --file --set=root /.disk/info; then
        search --file --set=root /.disk/mini-info
    fi
    set prefix=($root)/boot/grub
fi
if [ -e $prefix/$platform/grub.cfg ]; then
    source $prefix/$platform/grub.cfg
elif [ -e $prefix/grub.cfg ]; then
    source $prefix/grub.cfg
else
    source $cmdpath/grub.cfg
fi

cmdpath 是 efi 二进制文件的目录,因此它将回退到 efi 二进制文件相同目录中的 grub.cfg,如您所见。