跳转至内容

mkinitcpio

来自 ArchWiki

mkinitcpio 是一个用于创建 initramfs 镜像的 Bash 脚本。有关一般性介绍,请参阅 Arch 启动过程#initramfs

需要注意的是,在初始内存盘(initial ramdisk)阶段,执行各种任务有两种截然不同的方法:

基于 systemd 的初始内存盘(自版本 40 起成为新默认值)
systemd 在初始内存盘阶段开始时就已经启动。要执行的任务由常规的 systemd 单元文件决定。请参阅 systemd 启动过程
优点:与 systemd 生态系统的其余部分紧密集成,从而实现更一致、更精简的引导过程。可以更有效地并行化某些引导任务,在某些情况下可能会缩短总体引导时间。提供更全面的功能集,例如带有 /etc/crypttab.initramfssystemd-cryptsetup-generatorGPT 分区自动挂载
缺点:依赖项更多且体积更大:由于包含了 systemd 二进制文件及其依赖项,通常会导致 initramfs 更大。这可能会略微增加引导时间。
基于 Busybox 的初始内存盘
启动一个 init 脚本,该脚本反过来扫描初始内存盘的文件系统以查找要执行的脚本(在此上下文中称为运行时钩子)。
优点:轻量且体积较小,依赖项较少。

具体的变体由 /etc/mkinitcpio.confHOOKS 数组是否存在 systemd 钩子决定。有关更多详细信息,请参阅 #常用钩子

mkinitcpio 由 Arch Linux 开发者和社区贡献开发。请访问 公共 Git 仓库

安装

安装 mkinitcpio 软件包。由于它是 linux 软件包的依赖项,因此大多数用户应该已经安装了它。

高级用户可能希望通过 mkinitcpio-gitAUR 软件包从 Git 安装最新开发版本的 mkinitcpio

镜像创建与激活

自动生成

每当安装或升级内核时,pacman 钩子都会自动生成一个保存于 /etc/mkinitcpio.d/.preset 文件。例如官方稳定版 linux 内核包的 linux.preset。预设(preset)只是创建初始内存盘镜像所需的信息列表,无需手动指定各种参数和输出文件的位置。默认情况下,它仅包含创建第一个镜像的指令,第二个镜像必须明确启用:

  1. 按照 配置 中指定的指令创建的 default(默认)内存盘镜像。
  2. fallback(回退)内存盘镜像,与上述相同,但在创建过程中会跳过 autodetect(自动检测)钩子,从而包含支持大多数系统的全套模块。

创建预设后,pacman 钩子会调用 mkinitcpio 脚本,该脚本利用预设中提供的信息生成镜像。

注意: .preset 文件用于在内核更新后自动重新生成 initramfs;编辑它们时请务必小心。

手动生成

要手动运行该脚本,请参阅 mkinitcpio(8) 手册页。特别是,要基于内核包提供的预设(重新)生成 initramfs 镜像,请使用 -p/--preset 选项,后接要使用的预设。例如,对于 linux 包,使用以下命令:

# mkinitcpio -p linux

要基于所有现有预设(重新)生成 initramfs 镜像,请使用 -P/--allpresets 开关。这通常用于在更改全局 配置 后重新生成所有 initramfs 镜像。

# mkinitcpio -P

用户可以使用各种不同的配置创建任意数量的 initramfs 镜像。所需的镜像必须在相应的 引导加载程序 (boot loader) 配置文件中指定。

自定义生成

用户可以使用备选配置文件生成镜像。例如,以下命令将根据 /etc/mkinitcpio-custom.conf 中的指令生成一个初始内存盘镜像,并将其保存为 /boot/initramfs-custom.img

# mkinitcpio --config /etc/mkinitcpio-custom.conf --generate /boot/initramfs-custom.img

如果要为当前运行版本以外的内核生成镜像,请在命令行中添加内核版本号。已安装的内核版本可以在 /usr/lib/modules/ 中找到,其语法与每个内核执行 uname -r 命令的输出一致。

# mkinitcpio --generate /boot/initramfs-custom2.img --kernel 5.7.12-arch1-1

统一内核镜像 (UKI)

mkinitcpio 可以通过自身或经由 systemd-ukify 创建 统一内核镜像 (UKI)。如果缺少 systemd-ukify 或使用 --no-ukify 明确禁用它,则 UKI 将由 mkinitcpio 自身组装。此时将无法使用 ukify 的高级功能。

有关 UKI 生成的详细信息,请参阅 统一内核镜像

配置

mkinitcpio 的主配置文件是 /etc/mkinitcpio.conf。它也支持 Drop-in(补充)配置文件,例如 /etc/mkinitcpio.conf.d/myhooks.conf(如果使用 -c/--config 选项调用 mkinitcpio,且/或使用的预设包含 ALL_config,则不会考虑这些文件)。此外,内核包在 /etc/mkinitcpio.d 目录中提供了预设定义(例如 /etc/mkinitcpio.d/linux.preset)。

用户可以修改配置文件中的七个变量,详情请参阅 mkinitcpio.conf(5) § VARIABLES

MODULES
在运行任何引导钩子之前加载的内核模块。
BINARIES
要包含在 initramfs 镜像中的额外二进制文件。
FILES
要包含在 initramfs 镜像中的额外文件。
HOOKS
钩子是在初始内存盘中执行的脚本。
COMPRESSION
用于压缩 initramfs 镜像的程序。
COMPRESSION_OPTIONS
传递给 COMPRESSION 程序的额外参数。强烈建议不要使用此设置。mkinitcpio 会处理压缩器的特殊需求(例如向 xz 传递 --check=crc32),错误使用很容易导致系统无法启动。
MODULES_DECOMPRESS
是否解压可加载的内核模块和固件文件,还是保留其原始压缩形式。
  • 某些系统可能需要的钩子(如 lvm2mdadm_udevencrypt)默认情况下启用。请仔细阅读 #HOOKS 章节以获取说明。
  • 在版本 36 之前由 mkinitcpio 创建的预设文件设置了变量 ALL_config,这会阻止加载补充配置文件。要启用补充文件,请在旧预设文件中注释掉 ALL_config="/etc/mkinitcpio.conf" 这一行。

MODULES

MODULES 数组用于指定在执行其他任何操作之前要加载的模块。

后缀为 ? 的模块在未找到时不会抛出错误。这对于编译了特定模块(已在钩子或配置文件中明确列出)的自定义内核可能很有用。

  • 如果使用将在早期用户空间挂载的树外文件系统(例如将此类文件系统用作根文件系统),则必须将其模块(例如 reiser4)添加到 MODULES 数组中。
  • 当使用 encryptsd-encrypt 钩子时,如果目标系统与运行 mkinitcpio 的系统不同,则需要将系统引导期间解锁 LUKS 设备所需的键盘模块和/或文件系统添加到 MODULES 数组中。例如,如果您在 ext2 文件系统上使用密钥文件,但在运行 mkinitcpio 时未挂载 ext2 文件系统,请添加 ext2。有关详细信息,请参阅 dm-crypt/系统配置#cryptkey
  • 如果通过 USB 3 集线器使用键盘并希望用其解锁 LUKS 设备,请添加 usbhid xhci_hcd
  • 如果使用连接到扩展坞的显示器,您可能需要添加显卡模块以使 initrd 输出可见(例如大多数 Intel 显卡使用 i915)。

BINARIES 和 FILES

这些选项允许用户向镜像添加文件。BINARIESFILES 都在钩子运行之前添加,并可用于覆盖钩子使用或提供的文件。BINARIES 会在标准 PATH 中自动定位并进行依赖解析,这意味着任何所需的库也将被添加。FILES 则是按原样(as-is)添加。例如:

FILES=(/etc/modprobe.d/modprobe.conf)
BINARIES=(kexec)

请注意,由于 BINARIESFILES 都是 Bash 数组,因此可以添加多个以空格分隔的条目。

HOOKS

HOOKS 数组是文件中最重要的设置。钩子是描述将哪些内容添加到镜像中的小型脚本。对于某些钩子,它们还包含一个运行时组件,提供额外的行为,例如启动守护进程或组装堆栈块设备。钩子通过其名称引用,并按其在配置文件 HOOKS 数组中存在的顺序执行。

默认的 HOOKS 设置对于大多数简单的单磁盘设置应该足够了。对于堆栈或多块设备的根设备,如 LVMRAIDdm-crypt,请参阅相应的 wiki 页面了解进一步必要的配置。

构建钩子 (Build hooks)

构建钩子位于 /usr/lib/initcpio/install/,自定义构建钩子可以放置在 /etc/initcpio/install/。这些文件在 mkinitcpio 运行时由 bash shell 加载,并应包含两个函数:buildhelpbuild 函数描述将要添加到镜像中的模块、文件和二进制文件。由 mkinitcpio(8) 文档化的 API 用于方便添加这些项目。help 函数则输出该钩子功能的描述。

列出所有可用钩子:

$ mkinitcpio -L

使用 mkinitcpio-H/--hookhelp 选项可以输出特定钩子的帮助信息,例如:

$ mkinitcpio -H udev

运行时钩子 (Runtime hooks)

运行时钩子位于 /usr/lib/initcpio/hooks/,自定义运行时钩子可以放置在 /etc/initcpio/hooks/。对于任何运行时钩子,总应该有一个同名的构建钩子,它调用 add_runscript 将运行时钩子添加到镜像中。这些文件在早期用户空间由 busybox ash shell 加载。除了清理钩子外,它们将始终按 HOOKS 设置中列出的顺序运行。运行时钩子可能包含多个函数:

run_earlyhook:此名称的函数将在 API 文件系统挂载且内核命令行解析完成后运行。这通常是启动早期引导过程所需的额外守护进程(如 udev)的地方。

run_hook:此名称的函数在早期钩子之后不久运行。这是最常见的钩子点,组装堆栈块设备等操作应在此处进行。

run_latehook:此名称的函数在挂载根设备后运行。应谨慎使用此函数,用于进一步设置根设备或挂载其他文件系统(如 /usr)。

run_cleanuphook:此名称的函数尽可能晚地运行,并按其在配置文件 HOOKS 数组中列出的相反顺序运行。这些钩子应用于任何最后的清理工作,例如关闭由早期钩子启动的任何守护进程。

注意: 运行时钩子仅供 busybox init 使用。systemd 钩子会触发基于 systemd 的 init,它不运行任何运行时钩子,而是使用 systemd 单元。

后置钩子 (Post hooks)

后置钩子是位于 /usr/lib/initcpio/post/(由包提供)和 /etc/initcpio/post/(自定义)的执行文件或 shell 脚本。这些文件在镜像(重新)生成后执行,以便执行签名等额外任务。

每个可执行文件都会按以下顺序接收参数:

  1. 使用的 内核 (kernel)(在某些情况下可能为空);
  2. 生成的 initramfs 镜像
  3. (可选)生成的 统一内核镜像 (unified kernel image)

此外,还会设置以下环境变量:KERNELVERSION 为完整内核版本,KERNELDESTINATION 为内核为被引导而应位于的默认位置。

常用钩子

下表列出了常用钩子及其对镜像创建和运行时的影响。请注意,此表并不完整,因为软件包可以提供自定义钩子。

本文章或章节需要扩充。

待办事项: 添加关于 hostdatamemdisksleepstrip 的信息,查明 dmraid 等是否适用于/需要用于基于 systemd 的 initramfs。(在 Talk:Mkinitcpio#Improvements for the Common hooks table and section about systemd hook 中讨论)
busybox init systemd init 构建钩子 运行时钩子 (仅限 busybox init)
base 可选 设置所有初始目录并安装基础工具和库。除非您明确知道自己在做什么,否则请务必将此钩子保留为第一个钩子,因为在不使用 systemd 钩子时,它提供关键的 busybox init。

使用 systemd 钩子时是可选的,因为它只提供 busybox 恢复 shell。除了启用 base 外,您还需要暂时在 内核参数 中添加 SYSTEMD_SULOGIN_FORCE=1 才能使用该 shell。

udev systemd 向镜像添加 udevd、udevadm 和一小部分 udev 规则。 启动 udev 守护进程并处理来自内核的 uevent;创建设备节点。由于它不需要用户明确指定必要模块从而简化了引导过程,因此建议使用它。
usr 添加对独立分区上的 /usr 的支持。详情请参阅 #/usr 作为独立分区 在挂载真实根目录后挂载 /usr 分区。
resume 添加 lzolz4 内核模块,以便在使用非编译时默认的休眠镜像压缩算法时支持恢复。添加 systemd-hibernate-resume(8) 二进制文件,以支持从通过 HibernateLocation UEFI 变量指定的休眠镜像恢复。 尝试从“挂起至磁盘”状态恢复。有关进一步配置,请参阅 休眠 (Hibernation)
btrfs 设置所需的模块,以便为 Btrfs 使用多设备支持。您需要安装 btrfs-progs 才能使用此功能。在 filesystems 钩子已足够支持的单设备 Btrfs 上,不需要此钩子。 当不存在 udev 钩子或 systemd 钩子时,运行 btrfs device scan 以组装多设备 Btrfs 根文件系统。此钩子需要 btrfs-progs 包。
autodetect 通过扫描 sysfs 并创建模块白名单来缩小 initramfs 的体积。务必验证包含的模块是否正确且没有缺失。此钩子必须在其他子系统钩子之前运行,以便利用自动检测功能。放置在 'autodetect' 之前的任何钩子都将完整安装。
microcode (微代码) 在未压缩的 initramfs 镜像前附加 Intel 和 AMD 处理器的早期 微代码 (microcode) 更新文件。如果 /usr/lib/firmware/amd-ucode//usr/lib/firmware/intel-ucode/ 中有微代码文件则直接使用,否则提取 /boot/amd-ucode.img/boot/intel-ucode.img

如果 autodetect 钩子在此钩子之前运行,它将仅添加构建镜像的系统所属处理器的早期微代码更新文件。

使用此钩子取代了现已弃用的 --microcode 标志和预设文件中的 microcode 选项。这也允许您从引导配置中删除微代码 initrd 行,因为它们现在已与主 initramfs 镜像打包在一起。

modconf 包含来自 /etc/modprobe.d//usr/lib/modprobe.d/ 的 modprobe 配置文件。
kms 添加 GPU 模块以提供 早期 KMS 启动。此外还会添加某些笔记本电脑 LCD 面板内置隐私屏所需的模块。
keyboard (键盘) 添加键盘设备所需的模块。如果您拥有 USB 或串口键盘并需要在早期用户空间中使用(用于输入加密密码或在交互式 shell 中使用),请使用此钩子。作为副作用,可能会添加一些非键盘输入设备的模块,但不应依赖于此。
注意: 对于使用不同硬件配置引导的系统(例如外接键盘 vs. 内置键盘的笔记本电脑或 无头系统),此钩子需要放在 autodetect 之前,以便在引导时能够使用键盘,例如在使用 encrypt 钩子时解锁加密设备。
keymap sd-vconsole /etc/vconsole.conf 中指定的 控制台键映射 (keymap) 添加到 initramfs。如果您使用 系统加密,尤其是全盘加密,请确保在 encrypt 钩子之前添加它。 在早期用户空间加载 /etc/vconsole.conf 中指定的控制台键映射。
consolefont (控制台字体) /etc/vconsole.conf 中指定的 控制台字体 添加到 initramfs。 在早期用户空间加载 /etc/vconsole.conf 中指定的控制台字体。
block 添加块设备模块。如果 autodetect 钩子在此钩子之前运行,它将仅添加系统上使用的块设备的模块。例外情况是 ahcisd_modusb_storageuasmmc_blocknvmevirtio_scsivirtio_blk 模块,这些模块将始终无条件添加。
net (网络) 未实现 添加网络设备所需的模块。您必须安装 mkinitcpio-nfs-utils 才能使用此功能,详情请参阅 #使用网络 为基于 NFS 的根文件系统提供处理。
dmraid ? 为 fakeRAID 根设备提供支持。您必须安装 dmraid 才能使用此功能。请注意,如果您的控制器支持,更推荐在 fakeRAID 中将 mdadmmdadm_udev 钩子配合使用。详情请参阅 #使用 RAID 使用 dmraid 定位并组装 fakeRAID 块设备。
mdadm_udev 提供通过 udev 组装 RAID 阵列的支持。您必须安装 mdadm 才能使用此功能。详情请参阅 RAID#配置 mkinitcpio
encrypt sd-encrypt 向镜像添加 dm_crypt 内核模块和 cryptsetup 工具。您必须安装 cryptsetup 才能使用此功能。
注意: 请注意上述关于在引导期间解锁加密设备的 keyboard 钩子备注,以及在使用文件解锁时 #MODULES 中的文件系统备注。
检测并解锁加密根分区。有关进一步配置,请参阅 #运行时自定义

有关 sd-encrypt,请参阅 dm-crypt/系统配置#使用 systemd-cryptsetup-generator

lvm2 向镜像添加设备映射器 (device mapper) 内核模块和 lvm 工具。您必须安装 lvm2 才能使用此功能。如果您的根文件系统在 LVM 上,则这是必需的。
filesystems (文件系统) 这会在您的镜像中包含必要的文件系统模块。除非您在 MODULES 中指定了文件系统模块,否则此钩子是必需的
fsck 向镜像添加 fsck 二进制文件和特定文件系统的辅助程序,以便在挂载前对根设备(以及独立的 /usr,如果存在)运行 fsck。虽然建议每个人都添加此钩子,但如果您希望在引导时对 /usr 分区进行 fsck,则它是强制性的。没有此钩子,/usr 将永远不会被 fsck。如果包含此钩子,强烈建议同时也包含任何必要的模块以确保您的键盘在早期用户空间中工作。

使用此钩子需要在 内核命令行 中设置 rw 参数(讨论)。详情请参阅 fsck#引导时检查

acpi_override /usr/initcpio/acpi_override//etc/initcpio/acpi_override/ 中的 ACPI 机器语言 (.aml) 文件添加到早期未压缩的 initramfs 镜像中,以便内核可以在引导早期覆盖 ACPI 表(例如 DSDT)。[1]

COMPRESSION

内核支持多种 initramfs 压缩格式:gzipbzip2、lzma (xz)、xz、lzo (lzop)、lz4zstd。默认情况下,mkinitcpio 对 5.9 及以上版本的内核使用 zstd 压缩,对 5.9 以下版本的内核使用 gzip 压缩。

提供的 mkinitcpio.conf 中注释掉了各种 COMPRESSION 选项。如果您希望切换到另一种压缩方法,请取消注释其中一个,并确保您已安装相应的压缩工具。如果未指定,则使用默认方法。如果您希望创建未压缩的镜像,请在配置文件中指定 COMPRESSION=cat 或在命令行中使用 -z cat

提示
  • lz4 和 xz 压缩工具默认是多线程的,而 zstd 也会以多线程模式运行(使用 -T0 选项,该选项会尝试根据检测到的核心数生成尽可能多的线程)。
  • 在高压缩模式 (-9) 下,镜像的压缩比通常在 2.5 左右,而 lz4 的解压速度最快。对于略好一点的压缩效果,lzo 的解压速度也很快。zstd 提供了一个通用的解决方案,具有多线程压缩功能,并通过其选项提供广泛的压缩级别——请参阅 zstd(1) § Operation Modifiers。xz 在其高压缩预设 (-9) 下能达到最小体积,缩减系数约 5,但代价是解压速度慢得多。

COMPRESSION_OPTIONS

这些是传递给 COMPRESSION 指定的程序的额外标志,例如:

COMPRESSION_OPTIONS=(-9)

此选项可以留空;mkinitcpio 将确保任何支持的压缩方法都具有生成可用镜像所需的标志。

警告: 如果内核无法解包生成的归档文件,错误使用此选项可能会导致系统无法引导

在使用默认 zstd 压缩时,为了为自定义内核节省空间(特别是在使用 EFI 系统分区作为 /boot双系统 设置中),--long 选项非常有效。但是,内存有限的系统可能无法使用此选项解压 initramfs。如果您希望在生成 initramfs 期间查看详细信息,也可以使用 -v 选项。例如:

COMPRESSION="zstd"
COMPRESSION_OPTIONS=(-v -5 --long)

通过使用带有 -9e 压缩级别的 xz 并解压可加载的内核模块和固件,可以实现最高(但最慢)的压缩效果:

COMPRESSION="xz"
COMPRESSION_OPTIONS=(-9e)
MODULES_DECOMPRESS="yes"

MODULES_DECOMPRESS

MODULES_DECOMPRESS 控制在创建 initramfs 期间是否解压内核模块和固件文件。默认值为 no

Arch 使用 19 级的 zstd 压缩其 内核 模块和 linux-firmware。当为 initramfs 使用比这更高的压缩率时,设置 MODULES_DECOMPRESS="yes" 将允许进一步减小 initramfs 的大小。这是以引导早期增加 RAM 和 CPU 使用率为代价的,对内存有限或 CPU 性能较弱的系统有负面影响,因为内核解压整个 initramfs 镜像所花费的时间会比加载时解压单个模块和固件的时间更长。

提示: 在 initramfs 生成过程接近尾声时,所有剩余的 .bz2.gz.lz4.lzma.lzo.xz.zst 文件都会被移动到早期的未压缩 initramfs 镜像中,以避免二次压缩。

运行时自定义

本文章或章节需要扩充。

待办事项: 哪些选项适用于 systemd 钩子,哪些仅适用于 base?(在 Talk:Mkinitcpio 中讨论)

运行时配置选项可以通过内核命令行传递给 init 和某些钩子。内核命令行参数通常由引导加载程序提供。下面讨论的选项可以附加到内核命令行以更改默认行为。有关更多信息,请参阅 内核参数Arch 引导过程

来自 base 钩子的 init

root=
这是内核命令行中最重要的参数,因为它决定了哪个设备将被挂载为您真正的根设备。mkinitcpio 足够灵活,允许各种格式;示例请参阅 持久块设备命名#内核参数
注意: 以下引导参数会改变 initramfs 环境中 init 的默认行为。详情请参阅 /usr/lib/initcpio/init。当使用 systemd 钩子时,它们将不起作用,因为来自 base 钩子的 init 已被替换。
break
如果指定了 breakbreak=premountinit 会在引导过程(加载钩子之后,挂载根文件系统之前)暂停并启动一个交互式 shell,可用于排查故障。通过指定 break=postmount,可以在挂载根目录后启动此 shell。退出 shell 后将继续正常引导。
disablehooks=
通过添加 disablehooks=hook1[,hook2,...] 在运行时禁用钩子。例如:
disablehooks=resume
earlymodules=
通过 earlymodules=mod1[,mod2,...] 指定要尽早加载的模块,以改变模块加载顺序。(这可用于确保多个网络接口的正确顺序等场景。)

有关其他参数,请参阅 引导调试mkinitcpio(8)

使用 RAID

请参阅 RAID#配置 mkinitcpio

使用网络

注意: 目前尚不支持 NFSv4 FS#28287

所需软件包

net 需要安装 mkinitcpio-nfs-utils 包。

内核参数

详细且最新的信息可以在官方 内核文档 中找到。

ip=

此参数告诉内核如何配置设备的 IP 地址以及如何设置 IP 路由表。它可以接受最多九个由冒号分隔的参数:ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>:<ntp0-ip>

如果内核命令行中缺少此参数,则假设所有字段均为空,并应用 内核文档 中提到的默认值。通常这意味着内核会尝试使用自动配置来配置所有内容。

<autoconf> 参数可以单独作为 ip 参数的值出现(前面不带 : 字符)。如果值为 ip=offip=none,则不进行自动配置;否则将进行自动配置。最常用的方式是 ip=dhcp

有关参数解释,请参阅 内核文档

示例

ip=127.0.0.1:::::lo:none  --> Enable the loopback interface.
ip=192.168.1.1:::::eth2:none --> Enable static eth2 interface.
ip=:::::eth0:dhcp --> Enable dhcp protocol for eth0 configuration.
注意: 确保为 <device> 参数使用内核设备名称(例如 eth0),持久化名称(例如 enp2s0)将不起作用。详情请参阅 网络配置#网络接口

BOOTIF=

如果您有多个网卡,此参数可以包含您正在引导的接口的 MAC 地址。这通常很有用,因为接口编号可能会改变,或者与 pxelinux IPAPPEND 2 或 IPAPPEND 3 选项配合使用。如果未给出,将使用 eth0

示例

BOOTIF=01-A1-B2-C3-D4-E5-F6  # Note the prepended "01-" and capital letters.

nfsroot=

如果命令行中没有给出 nfsroot 参数,将使用默认值 /tftpboot/%s

nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]

运行 mkinitcpio -H net 获取参数解释。

使用 LVM

如果您的根设备在 LVM 上,请参阅 在 LVM 上安装 Arch Linux#添加 mkinitcpio 钩子

使用加密根分区

如果使用 加密根分区,请参阅 dm-crypt/系统配置#mkinitcpio 了解有关应包含哪些钩子的详细信息。

/usr 作为独立分区

如果您将 /usr 保留为独立分区,则必须遵守以下要求:

  • 添加 fsck 钩子,并在 /etc/fstab 中将 /usrpassno 标记为 2,以便在启动时检查该分区。虽然建议所有人使用,但如果您希望在引导时对 /usr 分区进行 fsck,则这是强制性的。没有此钩子,/usr 永远不会被 fsck。
  • 如果不使用 systemd 钩子,请添加 usr 钩子。这将在挂载根分区后挂载 /usr 分区。

技巧与提示

回退 (Fallback) initramfs 生成

从 mkinitcpio 版本 40 开始,回退 initramfs 生成默认已禁用。要启用它:

  • 调整 /etc/mkinitcpio.d/ 中相应的 .preset 文件:
    • 禁用 PRESETS=('default') 并改为启用 PRESETS=('default' 'fallback')
    • 启用 fallback_image="/boot/initramfs-linux-fallback.img"
    • 启用 fallback_options="-S autodetect"
  • 重新生成 initramfs。
  • 更新您的 引导加载程序 配置。
警告: 缺少回退 initramfs 可能会在默认 initramfs 失败时使您失去另一种进入系统的方式。请确保随手准备一个可引导的 安装介质 以备救援。

故障排除

提取镜像

如果您对 initramfs 镜像内部的内容感到好奇,可以提取它并查看其中的文件。

initramfs 镜像是一个 SVR4 CPIO 归档文件,通过 findbsdcpio 命令生成,可选使用内核可识别的压缩方案进行压缩。有关压缩方案的更多信息,请参阅 #压缩

mkinitcpio 包含一个名为 lsinitcpio(1) 的工具,它可以列出和/或提取 initramfs 镜像的内容。

您可以使用以下命令列出镜像中的文件:

# lsinitcpio /boot/initramfs-linux.img

并使用以下命令将它们全部提取到当前目录:

# lsinitcpio -x /boot/initramfs-linux.img

您还可以获得镜像中重要部分的更人性化的列表:

# lsinitcpio -a /boot/initramfs-linux.img

重新压缩修改后的已提取镜像

调用 /usr/bin/mkinitcpio 脚本的 build_image 函数,并带有参数:

build_image outfile compression

这可以通过创建一个包含 build_image 函数内容的新脚本并使用上述参数运行它来实现。这会将当前目录中的内容压缩到一个名为 outfile 的文件中。

警告: 在覆盖自动生成的 /boot/initramfs-linux.img 之前最好先重命名它,以便轻松撤销更改。做好操作失误导致系统无法引导的准备。如果发生这种情况,您需要通过回退镜像或引导 CD 引导以恢复原始镜像,运行 mkinitcpio 覆盖您的更改,或自行修复并重新压缩镜像。

已经挂载但显示 "/dev must be mounted"

mkinitcpio 用于确定 /dev 是否已挂载的测试是查看 /dev/fd/ 是否存在。如果其他一切看起来正常,可以通过以下方式手动“创建”它:

# ln -s /proc/self/fd /dev/

(显然,/proc 也必须挂载。mkinitcpio 本来就要求挂载它,这是它下一步要检查的内容。)

模块 XXXX 可能缺少固件

在内核更新后重新构建 initramfs 时,您可能会收到警告:

==> WARNING: Possibly missing firmware for module: 'module_name'

如果在生成 default(默认)initramfs 镜像时出现这些信息,那么正如警告所言,可能需要安装额外的固件。大多数常见的固件文件可以通过 安装 linux-firmware 软件包获得。对于提供固件的其他软件包,请参阅下表或尝试在 官方仓库AUR 中搜索模块名称。

否则,如果这些信息仅在生成 fallback(回退)initramfs 镜像时出现,您可以选择以下方案:

  • 如果您确定不使用受影响的硬件,可以安全地忽略这些警告。
  • 如果您想消除警告,可以安装缺失的固件。元软件包 mkinitcpio-firmwareAUR 包含了大多数可选固件。或者,手动安装所需的软件包:
模块 软件包 (Package)
aic94xx aic94xx-firmwareAUR
ast ast-firmwareAUR
bfa linux-firmware-qlogic
bnx2x linux-firmware-broadcom
liquidio linux-firmware-liquidio
mlxsw_spectrum linux-firmware-mellanox
nfp linux-firmware-nfp
qat_420xx linux-firmware-intel
qed linux-firmware-qlogic
qla1280 linux-firmware-qlogic
qla2xxx linux-firmware-qlogic
wd719x wd719x-firmwareAUR
xhci_pci
xhci_pci_renesas
upd72020x-fwAUR
  • 如果您想消除警告,但又不想在不需要的固件包上浪费系统空间,可以完全禁用 回退 initramfs 生成

对于不可用的固件,您可以通过创建空文件来消除警告,例如:

# echo "Device not available" > /usr/lib/firmware/qat_420xx.bin
# echo "Device not available" > /usr/lib/firmware/qat_420xx_mmp.bin

未发现 PS/2 控制器

在某些主板上(主要是老旧主板,但也包括少数新型主板),无法自动检测到 i8042 控制器。这种情况很少见,但肯定会有人遇到键盘无法使用的情况。您可以提前检测这种情况。如果您有 PS/2 端口并收到 i8042: PNP: No PS/2 controller found. Probing ports directly 信息,请将 atkbd 添加到 MODULES 数组中。[2]

标准救援程序

如果初始内存盘不正确,系统通常无法引导。请按照如下所示的系统救援程序进行操作:

在一台机器上启动成功,但在另一台机器上失败

mkinitcpioautodetect 钩子会通过扫描 /sys 和运行时的已加载模块,过滤掉主 initramfs 中不需要的 内核模块。如果您将 /boot 目录转移到另一台机器,且引导序列在早期用户空间失败,可能是因为缺少内核模块导致无法检测到新硬件。请注意,USB 2.0 和 3.0 需要不同的内核模块。

要修复此问题,首先尝试从 引导加载程序 中选择 fallback(回退)镜像,因为它没有经过 autodetect 过滤。引导成功后,在新机器上运行 mkinitcpio 以使用正确的模块重新构建主镜像。如果回退镜像也失败,请尝试引导至 Arch Linux live CD/USB,chroot 进入安装环境,并在新机器上运行 mkinitcpio。作为最后手段,尝试 手动 将模块添加到 initramfs。

无法打开控制台访问权限,root 账户已被锁定

systemd 钩子会 禁用 root 账户。要启用紧急 shell,请暂时在 内核参数 中添加 SYSTEMD_SULOGIN_FORCE=1

或者,您可以使用 initcpio-hook-shadowcopyAUR:安装该包,在 /etc/mkinitcpio.conf 中的 systemd 之后添加 shadowcopy 钩子,并使用 mkinitcpio -P 重新生成 initramfs。更多文档可在 其 GitHub 仓库 中找到。

参见