systemd-boot 安装失败

systemd-boot 安装失败

我在多重引导系统上用 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 的下一次修订,愿原力与你同在。

相关内容