跳转至内容

EFI 引导存根

来自 ArchWiki
(重定向自 EFISTUB)

EFI 引导存根(又称 **EFI stub**)是一个 EFI 可执行文件格式的内核,即可以直接从 UEFI 引导。

历史上,本文档和 Debian Wiki 使用了将这两个词合并的写法(EFISTUB 或 EFIStub)。

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

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

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

替代方案:统一内核镜像

统一内核镜像(UKI)本身就是一个 EFI 存根内核,它还包含 initramfs 和启动选项,全部打包在一个文件中。下表列出了与 UKI 相比,在从 UEFI 引导时,非 UKI 的 EFI 存根的特点。

非 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 有新版本并修复了 bug,请考虑使用制造商推荐的工具刷写它。
  • 此项可能已过时:某些固件(特别是 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 根分区。

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

如果省略,则将 /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 中使用 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 主板(如法国论坛上遇到的情况),在系统使用另一个已存在的引导项启动之前,不会注意到引导项的更改。

参见