前置知识:UEFI 下 Linux 的引导过程
由于 BIOS 下实现 TPM2 解密 LUKS 较为困难,本文仅介绍 UEFI 下 Linux 的引导过程。本文所给出的方案,也仅适用于 UEFI (非 CSM) 环境。
简单的说,UEFI 下 Linux 的引导过程如下:
- 读取 EFI 分区中的
EFI/BOOT/BOOTX64.EFI
,并执行。 - 该 EFI 程序找到
/boot
分区,并读取配置文件。这一步是可选的。 - 根据配置文件,加载 Linux 内核和 initramfs。这一步是可选的:大多数发行版都有 initramfs,如 Arch Linux、openSUSE、Ubuntu 等。一些嵌入式发行版没有 initramfs,如 OpenWrt。
- 执行 initramfs 的 init 脚本,init 脚本挂载主目录,然后使用 exec 启动 systemd 或其他 init 程序。
需要注意的是,引导器、initramfs 和系统 init 是三个不同的东西:
- 引导器:负责加载 Linux 内核和 initramfs,如 GRUB、systemd-boot、rEFInd 等。
- initramfs:一个微型的、用户态的 Linux 镜像,负责挂载主目录,启动系统 init 程序。常用的 initramfs 可能基于 busybox 或 systemd。
- 值得注意的是,initramfs 和 initramfs 生成器并不是同一个东西。常见的 initramfs 生成器有 dracut、mkinitcpio 等。
- 系统 init:是
PID=1
的进程,负责启动并管理进程和服务。常见的系统 init 有 systemd-init、sysvinit、OpenRC 等。- 事实上,早在 initramfs 时期,
PID=1
的进程就存在了。通常这个进程是一个 shell 脚本,但也有的 initramfs 不同。随后,initramfs 的 init 脚本会通过exec
方式启动系统 init。因此,它们具有相同的PID=1
。
- 事实上,早在 initramfs 时期,
此外,这三个东西一般情况下是可以自由组合的。可以使用「GRUB + Systemd-based initramfs + Systemd-init」,也可以使用「systemd-boot + Busybox-based initramfs + SysVinit」。主流的发行版选择的是「GRUB + Busybox-based initramfs + Systemd-init」。如果你非常喜欢 Systemd,那么你可以使用「Systemd-boot + Systemd-based initramfs + Systemd-init」。
兼容问题
- Systemd-boot 引导器
/boot
目录必须和/
在同一分区- 需要 EFI 驱动以支持 XFS、Btrfs 等文件系统,且 似乎 不支持 btrfs subvolume 作为根文件系统
- 需要修改
/root
分区的 GPT GUID 才能支持/
加密
- GRUB 引导器
- 不完整支持 LUKS2
- 不支持 TPM2/FIDO2 解密 LUKS
- Systemd-based initramfs
- 不支持 LUKS1
除了上述兼容问题外,由于引导器和 initramfs 无法互通加密密钥,每次启动您都要重复解锁两次 LUKS 卷。可以选择不加密 /boot
分区来解决此问题。