我在多重引导系统上用 systemd-boot 替换了 GRUB,该系统在离散分区上有多个 Ubuntu 20.04 和 22.04 实例,因为这些实例正在争夺引导加载程序 grubx64.efi 的控制权,而 systemd-boot 显然可以更好地管理这一点。
安装失败,无法配置。特别是,systemd-boot 会忽略已配置的启动项,并且系统通常会启动到 grub shell,需要手动启动。
我遵循的流程与建议一致。ESP 是 /dev/sda1,默认情况下挂载到 /boot/efi。启动分区是 /dev/sda2-7,其中 2、4 和 7 最相关,其他分区仅临时配置。首先,我运行:
# bootctl install
然后我配置了 /boot/efi/loader/loader.conf:
# /boot/efi/loader/loader.conf
# systemd-boot configuration file
timeout 5
#default 4fa9a5bf4498415ead7dea7c2724e90a-*
# From man loader.conf, Options, default, at https://www.freedesktop.org/software/systemd/man/loader.conf.html:
default @saved
console-mode keep
然后我在 /boot/efi/loader/entries 中的 .conf 文件中配置了启动项,所有启动项的形式如下:
# /boot/efi/loader/entries/sdx4.conf
# Boot entry configuration file.
title sdx4 - Ubuntu Desktop 22.04
linux ../vmlinuz
initrd ../initrd.img
options root=PARTUUID=9d1de6a4-452c-42d2-bf18-acee90032326 rw
然后,在建议的重启时,systemd-boot 会提供一个菜单,其中仅包含默认引导加载程序的选项,该默认引导加载程序会引导至 GRUB shell,并引导至 EFI 配置实用程序。
内核文件保留在 /boot 中,因为 linux-update-symlinks 在 /boot 中创建了符号链接 initrd.img 和 vmlinuz,而 FAT32 不支持符号链接。
bootctl status
返回
System:
Firmware: n/a (n/a)
Secure Boot: disabled
Setup Mode: user
TPM2 Support: no
Boot into FW: supported
Current Boot Loader:
Product: n/a
Features: ✗ Boot counting
✗ Menu timeout control
✗ One-shot menu timeout control
✗ Default entry control
✗ One-shot entry control
✗ Support for XBOOTLDR partition
✗ Support for passing random seed to OS
✗ Boot loader sets ESP information
ESP: n/a
File: └─n/a
Random Seed:
Passed to OS: no
System Token: set
Exists: yes
Available Boot Loaders on ESP:
ESP: /boot/efi (/dev/disk/by-partuuid/3aa3442b-045b-4b22-8e8b-6c01a5571ce7)
File: └─/EFI/systemd/systemd-bootx64.efi (systemd-boot 249.11-0ubuntu3.1)
File: └─/EFI/BOOT/BOOTX64.EFI
Boot Loaders Listed in EFI Variables:
Title: ubuntu
ID: 0x0000
Status: active, boot-order
Partition: /dev/disk/by-partuuid/3aa3442b-045b-4b22-8e8b-6c01a5571ce7
File: └─/EFI/ubuntu/shimx64.efi
Title: ubuntu
ID: 0x0002
Status: active, boot-order
Partition: /dev/disk/by-partuuid/3aa3442b-045b-4b22-8e8b-6c01a5571ce7
File: └─/EFI/debian/shimx64.efi
Title: Linux Boot Manager
ID: 0x0001
Status: active, boot-order
Partition: /dev/disk/by-partuuid/3aa3442b-045b-4b22-8e8b-6c01a5571ce7
File: └─/EFI/systemd/systemd-bootx64.efi
Title: UEFI OS
ID: 0x0005
Status: active, boot-order
Partition: /dev/disk/by-partuuid/3aa3442b-045b-4b22-8e8b-6c01a5571ce7
File: └─/EFI/BOOT/BOOTX64.EFI
Title: ubuntu
ID: 0x0006
Status: active, boot-order
Partition: /dev/disk/by-partuuid/3aa3442b-045b-4b22-8e8b-6c01a5571ce7
File: └─EFI/Ubuntu/grubx64.efi
Boot Loader Entries:
$BOOT: /boot/efi (/dev/disk/by-partuuid/3aa3442b-045b-4b22-8e8b-6c01a5571ce7)
Default Boot Loader Entry:
title: sdx7 - Ubuntu Desktop 22.04
id: sdx7.conf
source: /boot/efi/loader/entries/sdx7.conf
linux: ../vmlinuz
initrd: ../initrd.img
options: root=PARTUUID=67027db9-885b-471b-9c01-4b2108e6f7e9 rw
tree /boot/efi
返回
/boot/efi/EFI
├── BOOT
│ ├── BOOTX64.EFI
│ ├── fbx64.efi
│ └── mmx64.efi
├── debian
│ ├── BOOTX64.CSV
│ ├── grub.cfg
│ ├── grubx64.efi
│ ├── mmx64.efi
│ └── shimx64.efi
├── Linux
├── systemd
│ └── systemd-bootx64.efi
└── ubuntu
├── BOOTX64.CSV
├── grub.cfg
├── grubx64.efi
├── mmx64.efi
└── shimx64.efi
5 directories, 14 files
这是一场灾难。没有任何文档提供线索,谷歌也没有。任何关于如何让 systemd-boot 工作的建设性想法都将不胜感激。
答案1
这不完全是一个答案,但我分享我的配置是希望它能引导你找到自己的答案。
我的efi分区的内容如下:
tree -L 1
.
├── EFI
├── gparted
├── initramfs-linux-fallback.img
├── initramfs-linux.img
├── initramfs-linux-lts-fallback.img
├── initramfs-linux-lts.img
├── intel-ucode.img
├── loader
├── System Volume Information
├── vmlinuz-linux
└── vmlinuz-linux-lts
这为我提供了 Arch linux 主线内核和 lts 内核以及启动 gparted live 的选项。
加载程序目录包含:
.
├── entries
│ ├── arch.conf
│ ├── arch_lts.conf
│ ├── clonezilla.conf
│ └── gparted.conf
├── loader.conf
└── random-seed
arch.conf 文件包含:
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options root=UUID=66f01fdf-82a1-4aef-a7f6-27b3ba7bb790 rw
gparted.conf 文件包含:
title GParted Live
linux gparted/live/vmlinuz
initrd gparted/live/initrd.img
options apm=power-off boot=live live-media-path=/gparted/live/ username=user noswap noeject ip= net.ifnames=0
我确信,你所需要做的就是去掉
linux ../vmlinuz
initrd ../initrd.img
conf 文件的一部分。
如果您感兴趣的话,gparted conf 文件会启动 gparted live iso 的提取副本,该副本位于 gparted 目录中的 efi 分区上。它使用位于 gparted 目录树下方的 gparted initrd.img 和 vmlinuz。
希望这能为您找到可行的解决方案。请注意,当启动过程开始时,initrd.img 和 vmlinuz 文件必须位于 efi FAT 分区上,即“/”
答案2
事实证明systemd-boot没有实现引导加载程序规范。该命令bootctl list
是检查引导加载程序条目是否符合后者的语法。文档并返回:
title: sdx3 - Ubuntu Desktop 22.04
id: sdx3.conf
source: /boot/efi/loader/entries/sdx3.conf
linux: ../vmlinuz
initrd: ../initrd.img
options: root=PARTUUID=[UUID redacted] rw
title: sdx4 - Ubuntu Desktop 22.04
id: sdx4.conf
source: /boot/efi/loader/entries/sdx4.conf
linux: /vmlinuz (No such file or directory)
initrd: /initrd.img (No such file or directory)
options: root=PARTUUID=[UUID redacted] rw
因此我们看到,使用 ../ 路径将内核文件的位置指定为 EFI 系统分区挂载点的父目录不仅符合引导加载程序规范的语言(我应该赶紧补充一下,它不包含要求内核文件位于 ESP 上的语言),也符合实现它的代码。
除了我之外,其他人也浪费了很多精力。
Gummiboot 将会沉没。
使残骸浮起来的方法不是遵循引导加载程序规范、语法检查器或任何其他文档,而是像@PonJar 指出的那样,将内核文件移动到 ESP。
这需要进行一系列重新配置,包括手写大量安装脚本来彻底检查内核安装/升级过程,以及实际移除内核文件以移植到 ESP(嗯?)。本末倒置。
使 systemd-boot 符合引导加载程序规范,特别是通过允许它读取位于任何位置(包括正在引导分区的文件系统)的内核文件,将使上述所有内容变得没有必要。
事实上,systemd-boot 似乎在架构上存在缺陷,并且试图做太多事情。该kernel-install
命令及其相关bootctl
选项都只是为了弥补 systemd-boot 或 systemd-bootx64.efi 的执行限制而存在的。毕竟,它是一个引导加载程序,其全部目的是在另一个分区上执行内核,但它不能这样做,这就是复杂性的结果。
如果 systemd-boot 可以在已安装的位置执行内核,则所有必要的配置将是 loader.conf 和 /loader/entries .conf 文件。
我从以下来源直接或间接了解到了这一程序:这个帖子,并感谢发帖者 dalto,涉及:
将 ESP 安装到
/boot/efi
安装 efibootmgr;删除 grub*
zz-update-grub
从子目录中删除所有实例/etc/kernel
/etc/default/grub
将下面出现GRUB_CMDLINE_LINUX_DEFAULT
的所有内核命令行复制到/etc/kernel/cmdline
做
# bootctl install
创建并标记为可执行文件
/etc/kernel/postinst.d/zz-systemd-boot
:#!/bin/sh -e version="$1" bootopt="" # passing the kernel version is required if [ -z "${version}" ]; then echo >&2 "W: kernel-install: ${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" exit 2 fi # exit if kernel does not need an initramfs if [ "$INITRD" = 'No' ]; then exit 0 fi # avoid running multiple times if [ -n "$DEB_MAINT_PARAMS" ]; then' eval set -- "$DEB_MAINT_PARAMS" if [ -z "$1" ] || [ "$1" != "configure" ]; then exit 0 fi fi kernel-install add "$version" "/boot/vmlinuz-$version"
创建并标记为可执行文件
/etc/kernel/postrm.d/zz-systemd-boot
:#!/bin/sh -e version="$1" bootopt="" # passing the kernel version is required if [ -z "${version}" ]; then echo >&2 "W: kernel-install: ${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" exit 2 fi kernel-install remove "$version"
做:
sudo mkdir -p /etc/initramfs/post-update.d cd /etc/initramfs/post-update.d/ && sudo ln -s ../../kernel/postinst.d/zz-systemd-boot zz-systemd-boot
最后为当前内核运行 kernel-install。
等待 systemd-boot 的下一次修订,愿原力与你同在。