跳转至内容

EFI 引导存根

来自 ArchWiki

EFI 引导存根(也称为EFI stub)是一个 EFI 可执行文件格式的内核,也就是说它可以直接由 UEFI 引导。

历史上,本文档和 Debian Wiki 将这两个词作为一个整体使用(EFISTUB 或 EFIStub)。

默认情况下,Arch Linux 内核就是 EFI 引导存根。如果编译内核,请通过设置 CONFIG_EFI_STUB=y 来启用它。有关更多信息,请参阅 EFI 引导存根

继续之前,您需要一个 EFI 系统分区选择其挂载方式

提示
  • pacman 将直接更新 UEFI 读取的内核,如果您将 ESP 挂载到 /boot
  • EFI 引导存根也可以通过引导加载器间接引导。
    • 有几种 UEFI 引导管理器可以提供额外选项或简化 UEFI 引导过程。
    • 如果您正在尝试内核参数,或者您有多个内核/操作系统但主板的 UEFI 引导菜单不易使用,这一点尤其有用。
    • 具有针对内核和 initramfs 所在分区文件系统驱动程序的引导管理器(例如 rEFInd)允许将它们放在 ESP 之外。

替代方案:统一内核镜像

一个统一内核镜像(UKI)本身就是一个 EFI 存根内核,它还将 initramfs 和引导选项包含在一个文件中。下表列出了与 UKI 相比,非 UKI 的 EFI 存根的功能,当它们从 UEFI 引导时。

非 UKI 的 EFI 存根 统一内核镜像 (Unified kernel image)
initramfs 一个单独的文件,存储在ESP 包含
引导选项 存储在 UEFI 变量中 包含

当没有问题时,UKI 更简单,因为它只需要一个包含引导所需一切的文件。但是,对于非 UKI 内核,您可以例如在单个内核镜像之间切换不同的 initramfs 文件或尝试各种引导选项。对于 UKI,每次更改都会生成一个新的 UKI。

引导 EFI 引导存根

注意 传递给内核 EFI 引导存根的 initramfs 路径应相对于 EFI 系统分区的根目录,并使用反斜杠(符合 EFI 标准)。例如,如果 initramfs 位于 esp/EFI/arch/initramfs-linux.img,则相应的 UEFI 格式行应为 initrd=\EFI\arch\initramfs-linux.img。在以下示例中,我们将假设所有内容都在 esp/ 下。

直接使用 UEFI

UEFI 的设计目的是消除对 引导加载器(如 GRUB)的依赖。如果您的主板具有良好的 UEFI 实现,则可以将内核参数嵌入 UEFI 引导条目中,并由主板直接引导 Arch。您可以使用 efibootmgr 或 UEFI Shell v2 来修改主板的引导条目。

  • 过时的 UEFI 实现可能与 Linux 内核存在兼容性问题。如果您的 UEFI 有较新版本并包含错误修复,请考虑使用制造商推荐的工具进行刷写。
  • 此条目可能已过时:某些固件(特别是LenovoDell笔记本电脑)不会将 NVRAM 引导条目中的命令行参数传递给 EFI 二进制文件。(请参阅 2014 年 Arch BBS 上的此帖子)在这种情况下,可以使用统一内核镜像

efibootmgr

使用 efibootmgr 创建一个将加载内核的引导条目

# efibootmgr --create --disk /dev/sdX --part Y --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=block_device_identifier rw initrd=\initramfs-linux.img'

其中 /dev/sdXY 是 ESP 所在的驱动器和分区编号,root= 参数则对应您的 Linux 根分区。

注意 有关支持的设备名称格式,请参阅 内核参数,有关如何获取相应值,请参阅 持久性块设备命名,以及 持久性块设备命名#内核参数 以获取示例。

如果省略,则 /dev/sda 的第一个分区将用作 ESP。

请注意,带引号的 -u/--unicode 参数只是内核参数列表,因此您可能需要添加其他参数(例如,用于休眠到磁盘)。

一个包含 LTS Linux 内核、NVME 存储、带特定子卷的 BTRFS 文件系统以及在交换分区上休眠的示例

# efibootmgr --create \
 --disk /dev/nvme0n1 --part 1 \
 --label "EFISTUB Arch" \
 --loader /vmlinuz-linux-lts \
 --unicode 'root=UUID=01a40dd8-28f0-4636-be1e-aeed60c98095 resume=UUID=2d877d5d-4ca1-4d46-a3d6-b6ee94cbbd78 rw rootflags=subvol=@ loglevel=3 quiet initrd=\initramfs-linux-lts.img'

有关获取引导条目列表、设置引导顺序或删除它们的信息,请参阅 efibootmgr

提示

bcfg

某些 UEFI 实现使 efibootmgr 难以成功修改 NVRAM。如果 efibootmgr 无法成功创建条目,您可以使用 UEFI Shell v2(即从 Arch Linux live iso)中的 bcfg 命令。

首先,使用以下命令找出您的 ESP 所在的设备号:

Shell> map

在此示例中,使用 1 作为设备号。要列出 ESP 的内容:

Shell> ls FS1:

要查看当前的引导条目:

Shell> bcfg boot dump

要为您的内核添加一个条目,请使用:

Shell> bcfg boot add N FS1:\vmlinuz-linux "Arch Linux"

其中 N 是条目将在引导菜单中添加的位置。0 是第一个菜单项。已存在的菜单项将被移动到菜单中,但不会被丢弃。

您可以直接添加内核选项:

Shell> bcfg boot -opt N "root=/dev/sda2 initrd=\initramfs-linux.img"

或通过在 ESP 上创建文件:

Shell> edit FS1:\options.txt

在文件中,添加引导行。例如:

root=/dev/sda2 rw initrd=\initramfs-linux.img
注意 在文件中的行开头添加额外的空格。行开头有一个字节顺序标记,它会吞噬旁边的任何字符,导致引导时出现错误。

F2 保存,然后按 F3 退出。

将这些选项添加到您之前的条目中:

Shell> bcfg boot -opt N FS1:\options.txt

对任何其他条目重复此过程。

要删除先前添加的条目,请执行:

Shell> bcfg boot rm N

使用 UEFI Shell

如果您不想创建永久性引导条目,可以从 UEFI Shell 启动内核,因为它是一个普通的 UEFI 应用程序。

> FS0:
> \vmlinuz-linux root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rw initrd=\initramfs-linux.img

在这种情况下,内核参数作为普通参数传递给 EFI 引导存根内核。

为了避免每次都记住所有内核参数,您可以将可执行命令保存到一个 shell 脚本中,例如在您的 EFI 系统分区的 archlinux.nsh,然后使用以下命令运行它:

> FS0:
> archlinux

使用 startup.nsh 脚本

某些 UEFI 实现不会在冷启动之间保留 EFI 变量(例如 VirtualBox 6.1 版本之前的版本),并且通过 UEFI 设置的任何内容在关机后都会丢失。

UEFI Shell Specification 2.0 规定,ESP 分区根目录下的名为 startup.nsh 的脚本将始终被解释,并且可以包含任意指令;其中您还可以设置引导加载行。请确保将 ESP 分区挂载到 /boot 并创建一个包含内核引导加载行的 startup.nsh 脚本。例如:

vmlinuz-linux rw root=/dev/sdX [rootfs=myfs] [rootflags=myrootflags] \
 [kernel.flag=foo] [mymodule.flag=bar] \
 initrd=\initramfs-linux.img

此方法几乎适用于您可能在实际硬件上遇到的所有 UEFI 版本,您可以将其作为最后的手段。脚本必须是单行长命令。方括号内的部分是可选的,仅作为指导。Shell 风格的换行符仅用于视觉清晰。FAT 文件系统使用反斜杠作为路径分隔符,在这种情况下,反斜杠表示 initramfs 位于 ESP 分区的根目录下。

技巧与提示

带有备用内存盘的引导条目

如果没有引导管理器,内核命令行在引导时是不可更改的。为了至少拥有一种备用可能性,例如使用 initramfs-linux-fallback.img 和/或在没有 Intel 微码的情况下启动,只需使用 efibootmgr 创建另一个引导条目,例如标记为“Arch Linux fallback”并带有所需的备用选项。

ESP 上的 Archiso

可以将 Arch Linux ISO 放在 ESP 上以拥有一个恢复系统。截至 2025.08.01 版本,所需大小为 1.2G。

首先下载 archlinux-YYYY.MM.DD-x86_64.iso

接下来,在您的 ESP 中为 archiso 创建一个目录

# mkdir -p esp/EFI/archiso

arch 目录中的内容解压到其中

# bsdtar -v -x --no-same-permissions --strip-components 1 -f archlinux-YYYY.MM.DD-x86_64.iso -C esp/EFI/archiso arch

在最后一步,使用 efibootmgr 创建一个引导条目。替换以下内容:

diskpath 是设备路径(例如 /dev/sda)

diskpart 是分区号

# efibootmgr --create --disk diskpath \
--part diskpart \
--label "Arch (rescue system)" \
--loader '\EFI\archiso\boot\x86_64\vmlinuz-linux' \
--unicode 'archisobasedir=/EFI/archiso archisosearchfilename=/EFI/archiso/boot/x86_64/vmlinuz-linux initrd=\EFI\archiso\boot\x86_64\initramfs-linux.img'

现在您可以从 UEFI 引导加载器中选择救援系统。

故障排除

引导条目更改未生效

某些主板,例如 Haswell 时代(如法国论坛所遇到的)的 ASUS 主板,在系统未从另一个预先存在的引导条目启动时,不会注意到引导条目的更改。

参见