dracut
dracut 会为内核创建初始映像,用于预载访问根文件系统所需的块设备模块(如 IDE、SCSI 或 RAID)。安装 linux包 时,可以在 mkinitcpio 和 dracut 之间进行选择。Fedora、RHEL、Gentoo 和 Debian 等系统都使用 dracut,而Arch 默认使用mkinitcpio。
你可以在此查看 dracut 的完整项目文档。
安装 dracut包,你也可以安装 dracut-gitAUR 使用最新的开发版本。
dracut 的用法非常简单,而且通常就算在非标准环境下也不需要用户进行配置(如在 LUKS 上配置 LVM)。
使用如下命令为当前运行的内核生成 initramfs:
# dracut --hostonly --no-hostonly-cmdline --add-confdir no-network /boot/initramfs-linux.img
为了永久启用仅主机(hostonly)模式以便无需在命令行中进行指定,你可以在 dracut 的配置中添加:
/etc/dracut.conf.d/hostonly.conf
hostonly="yes" hostonly_cmdline="no"
dracut-gitAUR 已默认启用仅主机模式。
# dracut -f --regenerate-all
使用如下命令生成后备 initramfs:
# dracut /boot/initramfs-linux-fallback.img
/boot/initramfs-linux.img 指代输出的镜像文件。如果你使用了其它内核,请考虑更改文件名。例如,对于 linux-lts包 内核,输出文件应使用 /boot/initramfs-linux-lts.img。不过,只要引导加载程序的配置使用了相同的文件名,就可以随意命名这些文件。
--force 选项会覆写现有映像文件。
--kver 选项用于指定要使用的内核。该选项的输入需要匹配 /usr/lib/modules 目录下文件夹之一的名称。
其它选项可参考 dracut(8)。
要注意的是,initial ramdisk 阶段有两种执行各种任务的不同方式:
- 基于 Shell(bash/busybox/dash)的 initial ramdisk:该方式会启动一个初始化脚本,然后扫描 initial ramdisk 的文件系统来查找要执行的 dracut 脚本。
- 基于 systemd(默认)的 initial ramdisk:systemd 在 initial ramdisk 阶段时就已启动。具体要执行的任务由标准的 systemd 单元文件指定,相关信息可参考 systemd 启动流程。
这两种方式的主要区别在于 systemd dracut 模块的存在与否。详细信息请参考 #dracut 模块。
dracut 可通过直接传入命令行参数进行配置(参考 dracut(8) § OPTIONS)。如果你希望执行 dracut 命令时始终带上特定参数,可以在 /etc/dracut.conf.d/ 目录下的 .conf 文件中进行指定。例如:
/etc/dracut.conf.d/myflags.conf
hostonly="yes" compress="lz4" add_drivers+=" i915 " omit_dracutmodules+=" systemd network "
更多配置选项可参考 dracut.conf(5)。各个选项的完整说明可参考 dracut(8)。在下文中会对部分常用选项进行说明。
dracut 使用模块化流程构建 initramfs(参考 dracut.modules(7))。dracut 的所有内置模块位于 /lib/dracut/modules.d,可通过 dracut --list-modules 命令列出。更多模块可通过其它软件包提供(如 dracut-sshd-gitAUR)。遗憾的是,dracut 的内置模块缺乏文档说明,尽管它们的名称通常不言自明。
部分模块默认被激活/禁用,可通过 --add/--omit 选项分别激活或禁用,也可以在配置文件中使用 add_dracutmodules+="" 或 omit_dracutmodules+="" 持久化更改:
/etc/dracut.conf.d/myflags.conf
# ... add_dracutmodules+=" dracut modules to activate " omit_dracutmodules+=" dracut modules to deactivate " # ...
dracut 模块文档请参考上游文档。
大多数 dracut 模块都依赖于其它 dracut 模块。例如,蓝牙 dracut 模块就依赖于 dbus dracut 模块。
要使用 systemd 通过 systemd-cryptenroll 调用 TPM2 解锁 luks2 加密卷的功能,需要安装 tpm2-tools包 并启用 tpm2-tss dracut 模块。
可以通过 --force_drivers 命令行选项或 force_drivers+="" 配置项启用 dracut 早期加载功能(在 initramfs 阶段通过 modprobe 加载)。例如:
/etc/dracut.conf.d/myflags.conf
# ... force_drivers+=" nvidia nvidia_modeset nvidia_uvm nvidia_drm " # ...
内核命令行选项可放置在 /etc/dracut.conf.d/ 的 .conf 文件内,并通过 kernel_cmdline= 选项进行配置。Dracut 会自动读取配置,然后创建并写入到 initramfs /etc/cmdline.d/ 目录下的 01-default.conf 文件中。举个例子,你的内核命令行选项文件内容可能如下:
/etc/dracut.conf.d/cmdline.conf
kernel_cmdline="rd.luks.uuid=luks-f6c738f3-ee64-4633-b6b0-eceddb1bb010 rd.lvm.lv=arch/root rd.lvm.lv=arch/swap root=/dev/arch/root rootfstype=ext4 rootflags=rw,relatime"
不需要为 dracut 指定根块设备。参考 dracut.cmdline(7):
- 内核使用的根设备从来都是在启动配置文件的内核命令行选项中指定的。
不过,提前设置一些参数可能会很有用,而且还可以启用一些其它功能,如提示输入额外命令行参数。所有选项请参见 dracut.cmdline(7)。下面是一些配置选项示例:
- 从交换分区恢复:
resume=UUID=80895b78-7312-45bc-afe5-58eb4b579422 - 提示输入额外内核命令行参数:{ic|1=rd.cmdline=ask}}
- 在设定了
quiet的前提下输出更多信息:rd.info
dracut 可以通过 --uefi 命令行参数或 uefi="yes" 配置项生成统一内核映像。
你可以查看生成的映像的信息,并输出到单页上:
# lsinitrd /path/to/initramfs_or_uefi_image | less
该命令会列出生成映像时传入到 dracut 的参数、包含的 dracut 模块以及包含的所有文件。
要减少压缩生成映像所消耗的时间,可以更换使用的压缩软件。
只需添加下列任意一行(不能多选)到 dracut 配置文件中:
compress="cat" compress="gzip" compress="bzip2" compress="lzma" compress="xz" compress="lzo" compress="lz4" compress="zstd"
默认使用的是 gzip包。选择 compress="cat" 将不会压缩 initramfs。
你也可以使用非官方支持的压缩软件:
compress="program"
有些方法可以优化启动和生成 initramfs 的性能:
- 理解并配置最快的压缩方式。如果内核模块已经被压缩过,可能在生成 initramfs 时就不需要再次进行压缩。
- 理解在 initramfs 中添加 systemd 可能造成的影响。如果它会降低性能,就将其移除;如果会提升性能,就纳入进来。
- 在使用写时复制文件系统时,考虑使用 dracut-cpio。具体适用性请参考
--enhanced-cpio选项。
- 减少 initramfs 中嵌入的内核模块和 dracut 模块的数量。例如:如果安装了 nfs-utils包,但不依赖其进行启动,就需要显式移除 nfs dracut 模块,否则在默认配置下生成的 initramfs 会启用网络启动 - 详细信息请参考 https://github.com/dracut-ng/dracut-ng/pull/297 。
- 考虑使用 busybox包 dracut 模块替换掉 bash。
- 考虑使用
hostonly和hostonly_mode=strict。
linux包 和 dracut-gitAUR 包自带了用于在内核更新后自动生成新 initramfs 映像的 pacman 钩子。
-
dracut-ukifyAUR 软件包是使用 systemd-ukify包 生成统一内核映像的现代方法。与以下方法不同,你可以对整个内核映像签名,包括 initramfs。需要在 dracut 配置中使用
uefi_secureboot_cert和uefi_secureboot_key选项(dracut.conf(5))。 - 另外,如果你希望 initramfs 映像也是 EFI 可执行文件(即
esp/EFI/Linux/linux-kernel-machine_id-build_id.efi),也可以使用 dracut-uefi-hookAUR。在该目录下的 EFI 二进制文件会被 systemd-boot 自动检测到,因此不需要在/boot/loader/loader.conf中额外创建条目。
你还需要通过卸载 mkinitcpio包 或使用以下命令来阻止 mkinitcpio 创建和移除 initramfs 映像:
# ln -sf /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook # ln -sf /dev/null /etc/pacman.d/hooks/60-mkinitcpio-remove.hook
如果检测到了蓝牙键盘,dracut 会自动启用蓝牙模块。但 dracut 需要处于 hostonly 模式才能自动发现蓝牙键盘。
The limine-dracut-supportAUR package utilizes limine-entry-tool with dracut and pacman hooks to automate the installation and removal of kernels and boot entries in the Limine boot loader. See Limine#Boot entry automation for more information.
如果从休眠中恢复无效,你可能需要配置 dracut 以包含 resume 模块。添加一个配置文件:
/etc/dracut.conf.d/resume-from-hibernate.conf
add_dracutmodules+=" resume "
如果适用于你的系统,你可能也需要看下从加密交换分区恢复指南以及 dracut 特定指南。
如果内核无法自动发现并挂载 LVM / 软 RAID / LUKS 块设备,你可以加上以下内核命令行选项重新生成 initramfs:
rd.auto rd.lvm=1 rd.dm=1 rd.md=1 rd.luks=1
If you have issues booting or very long shutdown processes while the system waits for brltty, add the following to the dracut configuration line:
omit_dracutmodules+=" brltty "
Alternatively, uninstall brltty包 if it is not needed.
Cannot use whirlpool hash for keyslot encryption. Keyslot open failed. No usable keyslot is available.
A failure to boot with a message similar to the above typically will only require the user to include the crypt module via add_dracutmodules.