systemd-boot
systemd-boot(7),前身为 gummiboot(德语意为“橡皮艇”),有时也称为 sd-boot,是一个易于配置的 UEFI 引导管理器。它提供了一个文本菜单来选择引导条目,并提供了一个内核命令行编辑器。
请注意,systemd-boot 只能从其安装所在的 EFI 系统分区 或同一磁盘上的扩展引导加载程序分区 (XBOOTLDR 分区) 启动 EFI 可执行文件(例如 Linux 内核 EFI 引导存根、UEFI shell、GRUB 或 Windows 引导管理器)。
支持的文件系统
systemd-boot 继承了 来自固件 的文件系统支持(即至少支持 FAT12、FAT16 和 FAT32)。此外,它还会加载放置在 esp/EFI/systemd/drivers/ 中的任何 UEFI 驱动程序。
安装
systemd-boot 随 systemd 软件包一起分发,该软件包是 base 元软件包的依赖项,因此无需手动安装额外的软件包。
安装 UEFI 引导管理器
要安装 systemd-boot,请首先确保系统已在 UEFI 模式下引导,并且可以访问 UEFI 变量。可以通过运行 efivar --list 来验证,或者如果未安装 efivar,可以通过运行 ls /sys/firmware/efi/efivars(如果该目录存在,则表示系统已在 UEFI 模式下引导)来验证。
使用 bootctl(1) 将 systemd-boot 安装到 ESP
# bootctl install
这将把 systemd-boot UEFI 引导管理器复制到 ESP,为其创建一个 UEFI 引导条目,并将其设置为 UEFI 引导顺序中的第一项。
- 在 x64 UEFI 上,
/usr/lib/systemd/boot/efi/systemd-bootx64.efi将被复制到esp/EFI/systemd/systemd-bootx64.efi和esp/EFI/BOOT/BOOTX64.EFI。 - 在 IA32 UEFI 上,
/usr/lib/systemd/boot/efi/systemd-bootia32.efi将被复制到esp/EFI/systemd/systemd-bootia32.efi和esp/EFI/BOOT/BOOTIA32.EFI。
UEFI 引导条目将命名为“Linux Boot Manager”,并根据 UEFI 位数,指向 ESP 上的 \EFI\systemd\systemd-bootx64.efi 或 \EFI\systemd\systemd-bootia32.efi。
- 运行
bootctl install时,systemd-boot 会尝试在/efi、/boot和/boot/efi处定位 ESP。将esp设置为其他位置需要传递--esp-path=esp选项。(详细信息请参阅 bootctl(1) § OPTIONS。) - 安装 systemd-boot 将覆盖任何现有的
esp/EFI/BOOT/BOOTX64.EFI(或 IA32 UEFI 上的esp/EFI/BOOT/BOOTIA32.EFI),例如微软版本的该文件。 - 当在 pid 命名空间中运行时(例如 arch-chroot(8) 的非 systemd 模式),bootctl 不会操作 UEFI 变量/引导条目。要在 chroot 环境中创建引导条目,请改用
arch-chroot -S。
要完成安装,请 配置 systemd-boot。
使用 XBOOTLDR 进行安装
可以创建一个类型为“Linux extended boot” (XBOOTLDR) 的独立 /boot 分区,以将内核和 initramfs 与 ESP 分开。这对于 与 Windows 双启动 且现有 ESP 太小的情况特别有用。Grml 或 Archiso 也是可能的用例。
像往常一样准备 ESP,并在同一物理驱动器上创建另一个 XBOOTLDR 分区。XBOOTLDR 分区必须具有分区类型 GUID bc13c2ff-59e6-4262-a352-b275fd6f7172 [1](对于 gdisk 为 ea00 类型,对于 fdisk 为 xbootldr 类型)。XBOOTLDR 分区的大小应足够容纳您将要安装的所有内核。
- systemd-boot 不会像 ESP 那样进行文件系统检查。因此,可以使用您的 UEFI 实现能够读取的任何文件系统。
- 当启用“快速启动”(fast boot)模式时,UEFI 可能会跳过加载 ESP 以外的分区。这可能导致 systemd-boot 无法在 XBOOTLDR 分区上找到条目;在这种情况下,请禁用“快速启动”模式。
- XBOOTLDR 分区必须与 ESP 位于同一物理磁盘上,systemd-boot 才能识别它。
安装期间,将 ESP 挂载到 /mnt/efi,将 XBOOTLDR 分区挂载到 /mnt/boot。
进入 chroot 后,使用命令
# bootctl --esp-path=/efi --boot-path=/boot install
要完成安装,请 配置 systemd-boot。
更新 UEFI 引导管理器
每当有新版本的 systemd-boot 时,用户可以选择重新安装 UEFI 引导管理器。这可以手动或自动完成;下面介绍了这两种方法。
手动更新
使用 bootctl 更新 systemd-boot
# bootctl update
bootctl install 一样,systemd-boot 会尝试在 /efi、/boot 和 /boot/efi 处定位 ESP。将 esp 设置为其他位置需要传递 --esp-path=esp 选项。自动更新
要自动更新 systemd-boot,请使用 systemd 服务 或 pacman 钩子。下面介绍了这两种方法。
systemd 服务
从 250 版本开始,systemd 附带了 systemd-boot-update.service。启用此服务将导致 systemd-boot 在每次引导时运行以下命令
# bootctl --variables=no --graceful update
与 手动更新 一样,这将尝试在 /efi、/boot 或 /boot/efi 处定位 ESP。如果 /usr/lib/systemd/boot/efi/ 中有更新的版本,该命令将更新 ESP 中所有已安装的 systemd-boot 版本。它将首先寻找以 .efi.signed 结尾的 systemd-boot 文件,以允许用户对镜像进行签名以用于 安全启动。
pacman hook
软件包 systemd-boot-pacman-hookAUR 添加了一个 pacman 钩子,该钩子在每次升级 systemd 时执行。此钩子与 systemd 服务方法 的不同之处在于,它仅在升级 systemd 时尝试更新引导管理器,而不是每次引导时,并且它是立即执行,而不是等待下一次引导后。
与其安装 AUR 软件包,您可能更喜欢手动将以下文件放置在 /etc/pacman.d/hooks/ 中
/etc/pacman.d/hooks/95-systemd-boot.hook
[Trigger] Type = Package Operation = Upgrade Target = systemd [Action] Description = Gracefully upgrading systemd-boot... When = PostTransaction Exec = /usr/bin/systemctl restart systemd-boot-update.service
为安全启动签名
如果您启用了 安全启动,您可能希望添加一个 pacman 钩子,以便在每次软件包升级时自动对引导管理器进行签名
/etc/pacman.d/hooks/80-secureboot.hook
[Trigger]
Operation = Install
Operation = Upgrade
Type = Path
Target = usr/lib/systemd/boot/efi/systemd-boot*.efi
[Action]
Description = Signing systemd-boot EFI binary for Secure Boot
When = PostTransaction
Exec = /bin/sh -c 'while read -r f; do /usr/lib/systemd/systemd-sbsign sign --private-key /path/to/keyfile.key --certificate /path/to/certificate.crt --output "${f}.signed" "$f"; done;'
Depends = sh
NeedsTargets
将 /path/to/keyfile.key 和 /path/to/certificate.crt 分别替换为您自己的签名密钥和证书。为了更好地理解此钩子,请查阅 systemd-sbsign(1)。
创建的 /usr/lib/systemd/boot/efi/systemd-boot*.efi.signed 将被 bootctl install 或 bootctl update 自动拾取。请参阅 bootctl(1) § SIGNED .EFI FILES。
作为替代方案,请使用 sbctl。
配置
- 更改配置后,运行
bootctl(不带任何参数)以确保 systemd-boot 能够正确解析它。 - kernel-install 实用程序可用于自动生成与 systemd-boot 兼容的配置文件。本节介绍如何手动执行此操作。
引导加载程序配置
引导加载程序配置存储在文件 esp/loader/loader.conf 中。详细信息请参阅 loader.conf(5) § OPTIONS。
下面提供了引导加载程序配置示例
esp/loader/loader.conf
default arch.conf timeout 4 console-mode max editor no
default和timeout可以在引导菜单中自行更改,更改将存储为 UEFI 变量LoaderEntryDefault和LoaderConfigTimeout,从而覆盖这些选项。bootctl set-default ""和bootctl set-timeout ""可分别用于清除覆盖default和timeout选项的 UEFI 变量。- 如果您已设置
timeout 0,则可以通过按空格键进入引导菜单。 - 一个基本的引导加载程序配置文件位于
/usr/share/systemd/bootctl/loader.conf。 - 如果引导管理器在条目选择期间显示失真/使用了错误的分辨率,您可以尝试将
console-mode设置为auto(使用启发式方法选择最佳分辨率)、keep(保持固件提供的分辨率)或2(尝试选择第一个非 UEFI 标准分辨率)。
记住上一个条目
可以将 default 更改为 @saved,以便在启动时记住上次选择的条目。这在与 Windows 双启动且 Windows 自动更新意外将您推入 Linux 时非常有用。
esp/loader/loader.conf
default @saved ...
有关更多详细信息,请咨询 loader.conf(5)。
添加引导程序
systemd-boot 将搜索它从中启动的 EFI 系统分区 上 /loader/entries/ 中的 .conf 文件,此外还会搜索同一磁盘上的 XBOOTLDR 分区。
esp/loader/entries/*.conf中的条目只能使用esp/中的文件(例如内核、initramfs、镜像等),而boot/loader/entries/*.conf中的条目只能使用boot/中的文件。- 文件路径参数相对于您的 EFI 系统分区或 XBOOTLDR 分区的根目录。例如,如果您的 EFI 系统分区或 XBOOTLDR 分区挂载在
/boot上,则/boot/vmlinuz-linux文件必须在linux键中指定为/vmlinuz-linux。 - 当启用了 安全启动 时,带有嵌入式
.cmdline的 统一内核映像 (UKI) 将忽略传递给它们的所有命令行选项(无论是使用带有options的引导条目还是交互式传递)。当未启用安全启动时,通过命令行传递的选项会覆盖嵌入式的.cmdline。
使用其 UUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 从卷启动 Arch 的引导加载程序文件示例如下
esp/loader/entries/arch.conf
title Arch Linux linux /vmlinuz-linux initrd /initramfs-linux.img options root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx rw
esp/loader/entries/arch-fallback.conf
title Arch Linux (fallback initramfs) linux /vmlinuz-linux initrd /initramfs-linux-fallback.img options root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx rw
有关所有配置选项的详细信息,请参阅 引导加载程序规范。
systemd-boot 将在引导时自动检查位于 /EFI/Microsoft/Boot/Bootmgfw.efi 的 Windows 引导管理器、固件中的 Apple macOS 引导管理器、UEFI shell /shellx64.efi 和 EFI 默认加载程序 /EFI/BOOT/bootx64.efi,以及在 /EFI/Linux/ 中找到的特殊准备的内核文件。检测到后,将自动生成标题分别为 auto-windows、auto-osx、auto-efi-shell 和 auto-efi-default 的相应条目。这些条目不需要手动配置引导加载程序。但是,它不会自动检测其他 EFI 应用程序(与 rEFInd 不同),因此对于引导 Linux 内核,必须创建手动配置条目。
initrd 中指定 /boot/amd-ucode.img 或 /boot/intel-ucode.img,并且必须始终放在主 initramfs 镜像之前的第一位。UEFI Shell 或其他 EFI 应用程序
如果您通过软件包 edk2-shell 安装了 UEFI shell,如果 EFI 文件放置在 esp/shellx64.efi 中,systemd-boot 将自动检测并创建一个新条目。要执行此操作,安装软件包后的示例命令为
# cp /usr/share/edk2-shell/x64/Shell.efi /boot/shellx64.efi
否则,如果您将 其他 EFI 应用程序 安装到了 ESP 中,则可以使用以下片段。
efi 行的文件路径参数是相对于您的 EFI 系统分区 的根目录。如果您的 EFI 系统分区挂载在 /boot 上,并且您的 EFI 二进制文件位于 /boot/EFI/xx.efi 和 /boot/yy.efi,则您需要将参数分别指定为 efi /EFI/xx.efi 和 efi /yy.efi。esp/loader/entries/fwupd.conf
title Firmware updater efi /EFI/tools/fwupdx64.efi
esp/loader/entries/gdisk.conf
title GPT fdisk (gdisk) efi /EFI/tools/gdisk_x64.efi
Memtest86+
您需要安装 memtest86+-efi 才能使其正常工作。在使用安全启动时,还要对 EFI 二进制文件进行签名。
esp/loader/entries/memtest.conf
title Memtest86+ efi /memtest86+/memtest.efi
Netboot
systemd-boot 可以链式加载 Netboot。下载 ipxe-arch.efi EFI 二进制文件和签名,验证它,并将其按建议放置在 esp/EFI/arch_netboot/arch_netboot.efi 中。
esp/loader/entries/arch_netboot.conf
title Arch Linux Netboot efi /EFI/arch_netboot/arch_netboot.efi
GRUB
systemd-boot 可以链式加载 GRUB。grubx64.efi 二进制文件的位置与 GRUB 安装到 ESP 时使用的 --bootloader-id= 相匹配。
esp/loader/entries/grub.conf
title GRUB efi /EFI/GRUB/grubx64.efi
从其他磁盘引导
systemd-boot 无法 从其启动的 ESP 或同一磁盘上的 XBOOTLDR 分区以外的分区启动 EFI 二进制文件,但它可以引导 UEFI shell 来执行此操作。
首先,按照 上述描述 安装 edk2-shell。在 UEFI shell 中,使用 map 命令记下具有对应 PARTUUID 的分区的 FS 别名(例如:HD0a66666a2、HD0b、FS1 或 BLK7)。
然后,使用 exit 命令引导回 Linux,在那里您可以创建一个新的加载程序条目,以通过 UEFI shell 运行目标 EFI 程序
esp/loader/entries/windows.conf
title Windows efi /shellx64.efi options -nointerrupt -nomap -noversion HD0b:EFI\Microsoft\Boot\Bootmgfw.efi
确保 efi 路径与 shellx64.efi 在 esp 分区中复制的位置相匹配。另外,请注意,可以将 shellx64.efi EFI 文件移动到其他地方,以避免 systemd-boot 自动创建条目。
将 HD0b 替换为之前记下的 FS 别名。
-nointerrupt选项可防止使用Ctrl+c中断目标 EFI 程序。-nomap -noversion选项隐藏了默认的 UEFI shell 欢迎信息。- 如果目标 EFI 程序退出(例如由于错误),要使 UEFI shell 自动返回引导管理器,请添加
-exit选项。 - 如果 UEFI shell 中仍然存在不必要的输出,您还可以添加
-noconsoleout选项。
引导进入 UEFI 固件设置
如果您的设备固件支持从操作系统重启进入设置,systemd-boot 将自动添加一个条目以引导进入 UEFI 固件设置。
带密码保护的内核参数编辑器
或者,您可以安装 systemd-boot-passwordAUR,它支持 password 基本配置选项。使用 sbpctl generate 为此选项生成一个值。
使用以下命令安装 systemd-boot-password
# sbpctl install esp
启用编辑器后,在编辑内核参数之前,系统会提示您输入密码。
技巧与提示
引导菜单内的按键
您可以在菜单中使用 t 和 T 来调整菜单超时,使用 e 来编辑此引导的内核参数。按 h 查看有用的快捷键简表。有关引导菜单内可用按键绑定的完整列表,请参阅 systemd-boot(7) § KEY BINDINGS。
选择下一次引导
引导管理器与 systemctl 命令集成,允许您选择重启后要引导的选项。例如,假设您构建了一个自定义内核并创建了一个条目文件 esp/loader/entries/arch-custom.conf 来引导进入它,您只需启动
$ systemctl reboot --boot-loader-entry=arch-custom.conf
您的系统将重启进入该条目,同时保持默认选项完好无损,供后续引导使用。要查看可能条目的列表,请传递 --boot-loader-entry=help 选项。
如果您想直接引导进入主板的固件,则可以使用此命令
$ systemctl reboot --firmware-setup
统一内核镜像 (UKI)
esp/EFI/Linux/ 中的 统一内核映像 (UKIs) 会被 systemd-boot 自动获取,不需要在 esp/loader/entries 中添加条目。(请注意,统一内核映像必须具有 .efi 扩展名才能被 systemd-boot 识别。)
esp/loader/loader.conf 中没有设置 default,则会首先引导 esp/loader/entries/ 中的文件。请删除这些条目,或使用完整文件名设置默认值,即 default arch-linux.efiESP 上的 Grml
PKGBUILD:grml-systemd-bootAUR。Grml 是一个小型实时系统,包含用于系统管理和救援的软件集合。
为了在 ESP 上安装 Grml,我们只需要将内核 vmlinuz、initramfs initrd.img 和 squashed 镜像 grml64-small.squashfs 从 iso 文件复制到 ESP。为此,首先下载 grml64-small.iso 并挂载该文件(挂载点在此后记为 mnt);内核和 initramfs 位于 mnt/boot/grml64small/,squashed 镜像位于 mnt/live/grml64-small/ 中。
接下来,在您的 ESP 中为 Grml 创建一个目录,
# mkdir -p esp/grml
并将上述文件复制到其中
# cp mnt/boot/grml64small/vmlinuz esp/grml # cp mnt/boot/grml64small/initrd.img esp/grml # cp mnt/live/grml64-small/grml64-small.squashfs esp/grml
在最后一步中,为 systemd-boot 创建一个引导条目:在 esp/loader/entries 中创建一个 grml.conf 文件,内容如下
esp/loader/entries/grml.conf
title Grml Live Linux linux /grml/vmlinuz initrd /grml/initrd.img options apm=power-off boot=live live-media-path=/grml/ nomce net.ifnames=0
有关可用引导选项的概述,请咨询 Grml 的作弊码。
ESP 上的 Archiso
PKGBUILD:archiso-systemd-bootAUR。与 Grml 一样,可以使用 Arch Linux ISO。为此,我们需要将内核 vmlinuz-linux、initramfs initramfs-linux.img 和 squashfs 镜像 airootfs.sfs 从 ISO 文件复制到 EFI 系统分区。
首先下载 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
在最后一步中,为 systemd-boot 创建一个引导条目:在 esp/loader/entries 中创建一个 arch-rescue.conf 文件,内容如下
esp/loader/entries/arch-rescue.conf
title Arch Linux (rescue system) linux /EFI/archiso/boot/x86_64/vmlinuz-linux initrd /EFI/archiso/boot/x86_64/initramfs-linux.img options archisobasedir=/EFI/archiso archisosearchfilename=/EFI/archiso/boot/x86_64/vmlinuz-linux
有关可用引导选项的概述,请咨询 mkinitcpio-archiso 的 README.bootparams。
ESP 上带有安全启动的恢复 Arch 镜像
官方 Arch ISO 目前不支持 安全启动。因此,必须禁用安全启动才能引导进入 ISO 进行恢复或维护。这会破坏系统安全性,不是理想的方法。
另一种方法是使用 mkosi 创建一个已签名的 统一内核映像 (UKI),前提是安全启动已在您的系统上正确配置并运行。这使您能够在不禁用安全启动或随身携带 Arch ISO USB 驱动器的情况下引导进入已签名的恢复 Arch 环境。
https://swsnr.de/archlinux-rescue-image-with-mkosi/ 介绍了如何设置与安全启动兼容的 Arch 恢复镜像。一个实用的起点,带有您可以添加软件包的合理 mkosi 配置,可在 https://codeberg.org/swsnr/rescue-image 获得。
BIOS 系统上的 systemd-boot
如果您需要一个遵循 引导加载程序规范 的 BIOS 系统引导加载程序,则可以在 BIOS 系统上使用 systemd-boot。Clover 引导加载程序支持从 BIOS 系统引导,并提供模拟的 UEFI 环境。
故障排除
systemd-boot 不显示我的引导条目
这可能是由配置文件中的各种问题引起的,例如内核路径指定不正确。要进行检查,请运行
# bootctl
在 BIOS 模式下引导后安装
如果在 BIOS 模式下引导,仍然可以安装 systemd-boot,但是此过程要求您告诉固件在引导时启动 systemd-boot 的 EFI 文件
- 您在其他地方有一个正在运行的 UEFI Shell。
- 您的固件接口提供了一种正确设置在引导时需要加载的 EFI 文件的方法。
- 如果 UEFI 中没有设置其他条目,某些固件可能会使用默认的
esp/EFI/BOOT/BOOTX64.EFI。
如果您能做到,安装会更容易:进入您的 UEFI Shell 或固件配置接口,并将机器的默认 EFI 文件更改为 esp/EFI/systemd/systemd-bootx64.efi。
使用 efibootmgr 手动添加条目
如果 bootctl install 命令失败,您可以使用 efibootmgr 手动创建 UEFI 引导条目
# efibootmgr --create --disk /dev/sdX --part Y --loader '\EFI\systemd\systemd-bootx64.efi' --label "Linux Boot Manager" --unicode
其中 /dev/sdXY 是 EFI 系统分区。
\) 作为分隔符从 Windows 使用 bcdedit 手动添加条目
如果由于某种原因需要从 Windows 创建 UEFI 引导条目,可以在管理员提示符下使用以下命令
> bcdedit /copy "{bootmgr}" /d "Linux Boot Manager"
> bcdedit /set "{guid}" path \EFI\systemd\systemd-bootx64.efi
将 guid 替换为第一个命令返回的 id。您还可以将其设置为默认条目,使用
> bcdedit /default "{guid}"
Windows 升级后菜单消失
请参阅 UEFI#Windows 更改引导顺序。
添加对 Windows BitLocker TPM 解锁的支持
要停止 BitLocker 请求恢复密钥,请将以下内容添加到 loader.conf
esp/loader/loader.conf
reboot-for-bitlocker yes
这将设置 BootNext UEFI 变量,从而在不要求 BitLocker 恢复密钥的情况下加载 Windows 引导管理器。这是一个一次性的更改,systemd-boot 仍然是默认的引导加载程序。如果 Windows 已自动检测到,则无需将其指定为条目。
这是一个实验性功能,请务必咨询 loader.conf(5)。