For the complete documentation index, see llms.txt. This page is also available as Markdown.

Arch Linux UKI 启动

systemd-boot、UKI 与 DPS

前提

本文假设:

  1. 系统使用 UEFI、GPT、systemd-bootmkinitcpio

  2. 根文件系统是 Btrfs,系统子卷类似 @

  3. ESP 和 root 在同一块物理磁盘上。

  4. mkinitcpio 使用 systemd initramfs hook。没有这个 hook,root 分区不能只靠 DPS 自动发现。

  5. root 没有跨盘、RAID 或加密层。

  6. CPU 微代码包按机器实际情况选择:AMD 使用 amd-ucode,Intel 使用 intel-ucode

操作前先确认分区与挂载关系:

findmnt / /boot /efi
lsblk -f
sudo sgdisk -p /dev/nvme0n1

下面命令里的磁盘、分区号、UUID 都要替换成自己的实际值。

启用 systemd initramfs

省略 root= 依赖 initrd 阶段的 systemd-gpt-auto-generator。清空内核命令行之前,先确认 /etc/mkinitcpio.conf 里的 HOOKS 已经从传统 busybox 流程切到 systemd 流程:

grep '^HOOKS=' /etc/mkinitcpio.conf

普通未加密 Btrfs root 至少要包含 systemdblockfilesystems。如果原配置还在使用 udev,要先按自己的磁盘、键盘和文件系统情况迁移到 systemd hook 体系。加密 root、LVM、RAID 等场景需要对应的 systemd initramfs hook,不在本文范围内。

迁移 ESP 挂载点

把 ESP 从 /boot 迁移到 /efi,修改 /etc/fstab 中 ESP 对应行:

重新挂载,并重装内核与微代码。这样原本写进 ESP 的内核文件会释放到 Btrfs 管理的 /boot 目录下:

Intel CPU 把最后一行替换成:

设置 Btrfs 默认子卷

先找出系统根子卷 ID,例如 @ 对应的 ID:

假设目标 ID 是 256,把它设成文件系统默认挂载子卷:

这一步的意义是把“默认挂哪个子卷”写进 Btrfs 文件系统本身,而不是继续依赖内核命令行里的 rootflags=subvol=

设置 DPS 分区类型

DPS 依赖 GPT 分区类型。以 /dev/nvme0n1 为例,假设 ESP 是第 1 个分区,root 是第 3 个分区:

其中:

  1. ef00 是 EFI System。

  2. 8304 是 Linux x86-64 root。

ARM64、RISC-V 等架构要换成对应的 root 分区类型。修改后可以检查一次:

清空内核命令行

保留一个空的 /etc/kernel/cmdline,避免生成 UKI 时回退读取 /proc/cmdline 里的旧参数:

如果仍然需要 quietloglevel=lsm= 等参数,再显式写入这个文件。要做纯自动发现启动,就保持为空。

修改 mkinitcpio 预设

编辑 /etc/mkinitcpio.d/linux.preset,关闭传统 initramfs img 输出,启用 UKI 输出:

重点是删除或注释掉这些传统输出项:

重建引导环境

确认 /efi 已经挂载到 ESP 后,再删除本文会重新生成的旧启动产物:

删除 /efi/EFI/Linux/efi/loader 只应该在确认 /efi 正确挂载 ESP 后执行。否则删的就是根文件系统里的普通目录。

验证

检查 systemd-boot 是否识别到 UKI:

看到 arch-linux.efi 对应条目显示为 Type #2 (UKI, .efi) 后,即可重启验证。

参考

最后更新于