systemd-boot
systemd-boot(7)(有时被称为 sd-boot),曾用名 gummiboot (德语里“橡皮筏”的意思),是一款易于配置的 UEFI 引导加载程序。它提供了一个用于选择启动项的文本菜单,以及一个用于配置内核命令行的编辑器。
注意,systemd-boot 只能从安装到的 EFI 系统分区或同一硬盘上的扩展引导加载程序分区(XBOOTLDR 分区)启动 EFI 可执行程序(例如 Linux 内核 EFI boot stub,UEFI shell,GRUB 或者 Windows Boot Manager)。
systemd-boot 从固件继承了文件系统兼容性(例如至少支持 FAT12,FAT16 和 FAT32),还可以加载 esp/EFI/systemd/drivers/ 目录下的 UEFI 驱动。
systemd-boot 随 systemd包 包一同安装,其为 base包 元软件包的依赖,因此无需手动安装额外软件包。
要安装 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-path=esp参数指定esp目录(详细信息请参考 bootctl(1) § OPTIONS)。 - 安装 systemd-boot 将覆盖现有的
esp/EFI/BOOT/BOOTX64.EFI(或是 IA32 UEFI 下的esp/EFI/BOOT/BOOTIA32.EFI),例如 Microsoft 版本的文件。
要完成安装,请配置 systemd-boot。
可以单独创建一个“Linux extended boot”(XBOOTLDR)类型的 /boot 分区将内核和 initramfs 从 ESP 中分离出来,有助于在现有 ESP 过小的情况下配置 Arch + Windows 双系统。
跟随通常步骤配置 ESP,然后在同一物理硬盘上为 XBOOTLDR 创建另一分区。XBOOTLDR 分区的类型 GUID 必须是 bc13c2ff-59e6-4262-a352-b275fd6f7172 [1](gdisk 下是 ea00,fdisk 下是 xbootldr)。XBOOTLDR 的容量必须至少为要安装的所有内核的总大小。
- systemd-boot 不会像 ESP 那样检查 XBOOTLDR 的文件系统,因此可以使用你的 UEFI 实现可读取的任意文件系统类型。
- 在启用“快速启动”时,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。
每当 systemd-boot 有新版本时,用户可以选择重新安装启动管理器。该操作可以手动或自动进行,具体方式将在下文中描述。
使用bootctl 更新 systemd-boot:
# bootctl update
bootctl install 类似,systemd-boot 会尝试在 /efi,/boot 和 /boot/efi 三个位置下寻找 ESP。可以用 --esp-path=esp 参数指定 esp 位置。如果你需要自动更新 systemd-boot,你可以尝试使用 systemd 服务或 Pacman 钩子,下方介绍了这两种方法。
在版本 250 后, systemd包 添加了 systemd-boot-update.service。启用这个服务后将在每次启动系统时执行以下命令:
# bootctl --no-variables --graceful update
与手动更新类似,它会在 /efi、/boot 和 /boot/efi 目录下寻找 ESP。该命令将在 /usr/lib/systemd/boot/efi/ 目录下存在新版本时更新 ESP 中安装的所有 systemd-boot。它会先寻找以 .efi.signed 结尾的 systemd-boot 文件,以允许用户为安全启动对映像进行签名。
软件包 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
Depends = sbsigntools
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.
另一个选择是,使用 sbctl
bootctl 来确保 systemd-boot 能够正常读取配置内容。配置文件保存于 esp/loader/loader.conf,具体信息可参考 loader.conf(5) § OPTIONS 。
以下是一个简单的示例:
esp/loader/loader.conf
default arch.conf timeout 4 console-mode max editor no
- systemd-boot 不支持使用制表符进行缩进,请使用空格进行替代。
-
default和timeout可在启动选单中修改,变更将覆盖保存到LoaderEntryDefault和LoaderConfigTimeout这两个 UEFI 变量中。 -
bootctl set-default ""和bootctl set-timeout ""可分别用于清除覆盖了defaultandtimeout选项的 UEFI 变量。 - 如果你设置了
timeout 0,可以通过按下空格键来访问启动菜单。 - 基本配置文件示例位于
/usr/share/systemd/bootctl/loader.conf。 - 如果在选择启动项页面时菜单显示异常或分辨率不对,可以尝试将
console-mode设置为auto(启发式选择最佳分辨率),keep(保持固件提供的分辨率)或2(尝试使用第一个非 UEFI 标准的分辨率)。
可以将默认启动项设为 @saved 来记住上次使用的启动项。该选项对 Windows 双系统或 Windows 更新自动启动到了 Linux 的情况非常有用。
esp/loader/loader.conf
default @saved ...
更多信息请参考 loader.conf(5)。
systemd-boot 会在它启动的 EFI 系统分区下的 /loader/entries/ 目录和同硬盘下的 XBOOTLDR 分区中寻找 .conf 文件。
-
esp/loader/entries/*.conf下的启动项只能调用esp下的文件(例如内核,initramfs,映像等),boot/loader/entries/*.conf下的启动项也一样只能调用boot下的文件。 - 文件路径参数是相对于 EFI 系统分区或 XBOOTLDR 分区的根的。例如,如果你的 EFI 系统分区或 XBOOTLDR 挂载到了
/boot目录,那么就必须在linux参数中将/boot/vmlinuz-linux指定为/vmlinuz-linux。 - 启用安全启动后,内嵌
.cmdline的统一内核映像(UKI)将忽略所有传入的命令行选项(无论是使用options传入启动选项还是交互式传入的)。当未启用安全启动时,通过命令行传入的选项会覆盖掉.cmdline内置的选项。
以下为从卷启动 Arch 的启动选项文件示例,其中卷的 UUID 为 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:
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 Boot Manager,固件中的 Apple macOS Boot Manager,/shellx64.efi(UEFI shell)和 /EFI/BOOT/bootx64.efi(EFI Default Loader),同时也会在 /EFI/Linux/ 内查找内核文件。在检测到后,会自动生成名称分别为 auto-windows,auto-osx,auto-efi-shell 和 auto-efi-default 的启动选项,因此这些选项不需要手动配置引导器。但和 rEFInd 不同,不会为其它 EFI 应用程序创建启动选项,所以这些还需要进行进一步设置。
initrd 中指定 /boot/amd-ucode.img 或/boot/intel-ucode.img,并将其放置到主 initramfs 之前的首位。如果你通过 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+-efi包。如果使用了安全启动,需要同时对 EFI 二进制文件进行签名。
esp/loader/entries/memtest.conf
title Memtest86+ efi /memtest86+/memtest.efi
systemd-boot 可以串联加载网络引导。下载 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
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 alias(例如 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 路径和复制到 esp 路径下的 shellx64.efi 位置一致。顺带一提,可以将 shellx64.efi EFI 文件移动到其它位置来防止 systemd-boot 自动创建启动选项。
将 HD0b 替换为之前记录的 FS alias。
-
-nointerrupt选项可以避免通过Ctrl+c选项终端目标 EFI 程序允许。 -
-nomap -noversion选项会隐藏掉默认 UEFI shell 欢迎信息。 - 如需让 UEFI shell 在目标 EFI 程序退出后(如出现错误等原因)自动回到启动引导器,可以添加
-exit选项。 - 如果 UEFI shell 还会出现无用输出,可以添加
-noconsoleout选项。
如果你设备的固件支持从操作系统重启到固件设置,那 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
位于 esp/EFI/Linux/ 的统一内核映像会自动地被 systemd-boot 识别,无需在 esp/loader/entries 中添加条目。需要注意的是,拥有.efi 扩展名的统一内核镜像才会被 systemd-boot 识别。
esp/loader/loader.conf 中未设置 default,则会优先启动位于 esp/loader/entries/ 的文件。请移除这些条目,或使用完整档名来设置预设项目,例如 default arch-linux.efi
Grml 是精简的 Live 系统,包含一系列用于系统管理和救援的软件。
如需将 Grml 安装到 ESP,只需将 iso 镜像中的内核文件 vmlinuz、initramfs 镜像 initrd.img 和压缩镜像 grml64-small.squashfs 复制到 ESP.
首先,下载 grml64-small.iso 并挂载(下文中称挂载点为 mnt); 内核和 initramfs 位于 mnt/boot/grml64small/,压缩镜像位于 mnt/live/grml64-small/。
然后,在你的 ESP(EFI 系统分区)中新建一个 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
最后在 esp/loader/entries 中创建一个 grml.conf 文件,以在 systemd-boot 中创建一个启动项:
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
要查看所有可用引导选项,请参考 cheatcode for Grml。
与 Grml 相同,也可以使用 Arch Linux 的 ISO 创建启动环境。为此,需要将 ISO 文件中的以下内容复制到 EFI 系统分区(ESP):
内核文件:vmlinuz-linux
初始内存盘:initramfs-linux.img
压缩的根文件系统映像:airootfs.sfs
这些文件是系统启动所需的基本组件。后续步骤将说明如何挂载 ISO 并执行文件复制操作。
第一步,下载 archlinux-YYYY.MM.DD-x86_64.iso
然后,在 EFI 系统分区(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
最后在 esp/loader/entries 中创建一个 arch-rescue.conf 文件,以便在 systemd-boot 中添加一个启动项:
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
如需了解可用的开机选项,参见 README.bootparams for mkinitcpio-archiso。
官方的 Arch ISO 目前不支持安全启动。所以,进入 ISO 进行恢复或者维护前必须禁用安全启动。这也会破坏系统的安全性,并不是个好办法。
一个可能的选择是使用 mkosi 创建签名的统一内核映像,前提是系统上的安全启动已经正确配置并可以运行。这可以让你引导进一个签名的 Arch 恢复环境而无需禁用安全启动或随身携带一个 ISO USB 驱动器。
https://swsnr.de/archlinux-rescue-image-with-mkosi/ 描述了配置兼容安全启动的 Arch 恢复镜像的方法。开箱即用的 mkosi 配置可在 https://codeberg.org/swsnr/rescue-image 获取,可以自行添加软件包。
如果需要一个符合 The Boot Loader Specification 的 BIOS 系统启动加载器,也可以使用 systemd-boot. Clover 支持在 BIOS 系统中启动并模拟一个 UEFI 环境(以便使用 systemd-boot).
该问题可能是由配置文件问题(如内核路径错误)导致的。可以执行以下命令进行检查:
# bootctl
如果你以 BIOS 模式启动电脑,你还是可以正常安装 systemd-boot,但需要在安装后手动向你的固件提供如何启动 systemd-boot EFI 文件的相关信息,为此你需要下列工具之一:
- 一个 UEFI Shell
- 你的 UEFI 固件设置中提供了更改启动选项的选项.
- 如果 UEFI 没有其它启动项,某些固件会直接使用
esp/EFI/BOOT/BOOTX64.EFI。
满足条件后,进入你的 UEFI Shell 或是 UEFI 固件设置,修改你的默认 EFI 启动加载器为 esp/EFI/systemd/systemd-bootx64.efi 。
如果运行bootctl install 命令失败,你可以通过 efibootmgr包手动增加选项:
# efibootmgr --create --disk /dev/sdX --part Y --loader '\EFI\systemd\systemd-bootx64.efi' --label "Linux Boot Manager" --unicode
用 EFI 系统分区的设备名称替换 /dev/sdXY 。
如需从 Windows 添加 UEFI 启动入口,你可以用管理员权限执行这些指令:
> bcdedit /copy {bootmgr} /d "Linux Boot Manager"
> bcdedit /set {guid} path \EFI\systemd\systemd-bootx64.efi
用第一条指令返回的 id 替换 guid. 你也可以使用以下指令将它设置为默认入口:
> bcdedit /default {guid}
在 loader.conf 中添加以下内容以阻止 BitLocker 请求恢复密钥:
esp/loader/loader.conf
reboot-for-bitlocker yes
这一步会设定 BootNext UEFI 变量,从而无需使 BitLocker 请求恢复密钥就能加载 Windows Boot Manager。该操作只需进行一次,且 systemd-boot 仍是默认引导加载程序。如果已自动检测到 Windows,则无需将其指定为条目。
注意,这是实验性功能,使用前请查阅 loader.conf(5)。