EFI 引导存根
EFI 引导存根(又称 **EFI stub**)是一个 EFI 可执行文件格式的内核,即可以直接从 UEFI 引导。
历史上,本文档和 Debian Wiki 使用了将这两个词合并的写法(EFISTUB 或 EFIStub)。
默认情况下,Arch Linux 内核就是 EFI 引导存根。如果 编译内核,请通过设置 CONFIG_EFI_STUB=y 来激活它。更多信息请参阅 EFI 引导存根。
继续操作之前,您需要一个 EFI 系统分区 并 选择挂载方式。
替代方案:统一内核镜像
统一内核镜像(UKI)本身就是一个 EFI 存根内核,它还包含 initramfs 和启动选项,全部打包在一个文件中。下表列出了与 UKI 相比,在从 UEFI 引导时,非 UKI 的 EFI 存根的特点。
| 非 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 有新版本并修复了 bug,请考虑使用制造商推荐的工具刷写它。
- 此项可能已过时:某些固件(特别是 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 中使用 bcfg 命令(即从 Arch Linux live iso)。
首先,找到您的 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 规定,名为 startup.nsh 的脚本位于 ESP 分区根目录,将始终被解释并可以包含任意指令;其中您可以设置一个引导加载行。请确保将 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 的引导项
没有引导管理器的情况下,内核命令行在启动时无法更改。为了至少有一种备用可能性,例如使用 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 主板(如法国论坛上遇到的情况),在系统使用另一个已存在的引导项启动之前,不会注意到引导项的更改。