EFI 引导存根
EFI 引导存根(也称为EFI stub)是一个 EFI 可执行文件格式的内核,也就是说它可以直接由 UEFI 引导。
历史上,本文档和 Debian Wiki 将这两个词作为一个整体使用(EFISTUB 或 EFIStub)。
默认情况下,Arch Linux 内核就是 EFI 引导存根。如果编译内核,请通过设置 CONFIG_EFI_STUB=y 来启用它。有关更多信息,请参阅 EFI 引导存根。
替代方案:统一内核镜像
一个统一内核镜像(UKI)本身就是一个 EFI 存根内核,它还将 initramfs 和引导选项包含在一个文件中。下表列出了与 UKI 相比,非 UKI 的 EFI 存根的功能,当它们从 UEFI 引导时。
| 非 UKI 的 EFI 存根 | 统一内核镜像 (Unified kernel image) | |
|---|---|---|
| initramfs | 一个单独的文件,存储在ESP中 | 包含 |
| 引导选项 | 存储在 UEFI 变量中 | 包含 |
当没有问题时,UKI 更简单,因为它只需要一个包含引导所需一切的文件。但是,对于非 UKI 内核,您可以例如在单个内核镜像之间切换不同的 initramfs 文件或尝试各种引导选项。对于 UKI,每次更改都会生成一个新的 UKI。
引导 EFI 引导存根
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 有较新版本并包含错误修复,请考虑使用制造商推荐的工具进行刷写。
- 此条目可能已过时:某些固件(特别是Lenovo和Dell笔记本电脑)不会将 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/sdX 和 Y 是 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。
- 您可以使用 kesboot-gitAUR 包来简化和自动化此过程:它还包含一个pacman hook,可以在软件包操作期间添加和删除 EFI 变量。
- https://github.com/de-arl/auto-UEFI-entry 是一个用于创建命令的 bash 助手。
- 将创建引导条目的命令保存在 shell 脚本中会很方便,这样更容易修改,例如在更改内核参数时。在此过程中,请考虑自动化删除旧的引导条目,因为 efibootmgr 目前不支持编辑现有条目。
- 标题为 内置引导加载器的 Linux 内核 的论坛帖子也可能很有趣。
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 主板,在系统未从另一个预先存在的引导条目启动时,不会注意到引导条目的更改。