某天在群里和大佬们作OT的闲聊时觉得 GRUB 作为 Bootloader 过于臃肿,于是就产生了更换一个更轻量的 Bootloader 的想法。
因为 systemd-boot 与 systemd 关系紧密,而且有一些其他 Bootloader 没有的优秀特性,我决定更换这个 Bootloader 。
安装 systemd-boot
首先需要安装 systemd-boot
注意使用 systemd-boot 时需要将 ESP 挂载为 Boot 分区。
这里假设只有一个 ESP ,如果有多个 ESP ,需要指定额外的参数。
bootctl install
配置 systemd-boot
systemd-boot 需要自行编写配置文件和启动项配置。
Bootloader 配置
创建并编辑 /boot/loader/loader.conf
文件:
#timeout 10
#console-mode keep
default arch.conf
timeout
即菜单超时,默认值为 0 。为 0 时自动引导默认启动项,若开机时按下按键(不是所有按键都有用,可以按空格),将显示菜单。个人很喜欢这个设计,既可以节省宝贵的一秒钟,还不会牺牲扩展性。
console-mode
默认值为 keep 。最好别动,否则启动菜单可能不会以屏幕分辨率呈现。
default
为初始的默认启动项,值为 /boot/loader/entries/
下的文件名,此处为 arch.conf
,则 entries 文件夹下必须存在一个叫 arch.conf
的启动项文件。默认启动项可以使用 bootctl
覆盖或在启动菜单里使用 D
键指定默认启动项。
一般写这么多就够了。
启动项配置
创建并编辑 /boot/loader/entries/arch.conf
文件:
title Arch Linux Zen Kernel
linux /vmlinuz-linux-zen
initrd /amd-ucode.img
initrd /initramfs-linux-zen.img
options root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx rw
格式大致如上。
title
是该启动项在菜单中的显示名称
linux
, initrd
, options
是引导 Linux 系统必需的参数,可以参考 GRUB 的配置文件修改。
此处要注意不同版本内核的内核文件名不一致,需要修改。我使用的是 Linux-zen 内核,所以这里的内核文件带 zen 后缀。
别忘了添上微码补丁的加载项。
内核参数可以从 /boot/grub/grub.cfg
中去抄。不要从 /etc/default/grub
里抄,可能会少参数。
还可以创建一个 fallback entry
。参考 GRUB ,不过用处不大。
如果只是使用 LUKS 加密系统(或者没加密),完成这一步就可以卸载 GRUB 重启了。
配置安全启动
如果还设置了安全启动,需要继续配置内核自动签名。ArchWiki1 提供了两种方法,这里依旧手动配置 pacman hook 。
关于安全启动的详细配置过程,请参考这篇文章。
配置 pacman hook
如果使用 GRUB 时按照上面的教程配置了 HOOK ,这里需要删除这些 HOOK 。
/etc/pacman.d/hooks/90-mkinitcpio-install.hook
/usr/local/share/libalpm/scripts/mkinitcpio-install
创建两个新 HOOK
内核或
systemd
更新时触发签名 Kernel 和 Bootloader 的 HOOK/etc/pacman.d/hooks/99-secureboot.hook
[Trigger] Type = Package Operation = Install Operation = Upgrade Target = systemd Target = usr/lib/modules/*/vmlinuz Target = usr/lib/initcpio/* [Action] Description = Signing Kernel for SecureBoot When = PostTransaction Exec = /usr/bin/sh -c "/usr/bin/find /boot/ -type f \( -name 'vmlinuz-*' -o -name 'systemd*' \) -exec /usr/bin/sh -c 'if ! /usr/bin/sbverify --list {} 2>/dev/null | /usr/bin/grep -q \"signature certificates\"; then /usr/bin/sbsign --key db.key --cert db.crt --output {} {}; fi' \;" Depends = sbsigntools Depends = findutils Depends = grep
需要将
db.key
和db.crt
修改为对应的绝对路径。systemd
更新时触发更新systemd-boot
的 HOOK/etc/pacman.d/hooks/100-systemd-boot.hook
[Trigger] Type = Package Operation = Upgrade Target = systemd [Action] Description = Updating systemd-boot When = PostTransaction Exec = /usr/bin/bootctl update
这个 HOOK 做了一些修改(参考 GRUB 的 HOOK),兼容所有内核。
注意更新 Bootloader 的 HOOK 必须比签名 HOOK 先执行。
这里 systemd-boot.hook 使用 100 作为前缀,好像看起来 99 排在 100 前面,但 Linux 的文件排序是逐字符对比排序的,所以 100 要比 99 先执行。
签名 systemd-boot
最后需要手动执行一次签名操作:
sbsign --key db.key --cert db.crt --output /boot/EFI/systemd/systemd-bootx64.efi /boot/EFI/systemd/systemd-bootx64.efi
sbsign --key db.key --cert db.crt --output /boot/EFI/BOOT/BOOTX64.EFI /boot/EFI/BOOT/BOOTX64.EFI
同样需要将 db.key
和 db.crt
修改为对应的绝对路径。
卸载 GRUB
sudo pacman -R grub os-prober
卸载完后 pacman 会提示有两个文件被转移,这两个文件也要删掉。
然后删除 Boot 分区中的 grub 文件夹和 ESP 中的 grub 启动文件,最后用 efibootmgr
清理掉残留的 GRUB 启动项即可。