mkinitcpio
mkinitcpio 是一个 Bash 脚本,用于创建 initial ramdisk 环境。引自 mkinitcpio(8) 手册页
- 初始 ramdisk 本质上是一个非常小的环境(早期用户空间),它加载各种内核模块并在将控制权移交给
init
之前设置必要的配置。这使得例如,在软件 RAID 阵列上拥有加密的根文件系统和根文件系统成为可能。mkinitcpio 允许通过自定义 hook 轻松扩展,具有运行时自动检测和许多其他功能。
传统上,内核负责 启动过程 早期阶段的所有硬件检测和初始化任务,然后在挂载根文件系统并将控制权传递给 init
之前完成。然而,随着技术的进步,这些任务变得越来越复杂。
如今,根文件系统可能位于各种硬件上,从 SCSI 到 SATA 再到 USB 驱动器,由来自不同制造商的各种驱动控制器控制。此外,根文件系统可能会被加密或压缩;位于软件 RAID 阵列或逻辑卷组中。处理这种复杂性的简单方法是将管理传递到用户空间:初始 ramdisk。另请参阅:/dev/brain0 » 博客存档 » Arch Linux 中的早期用户空间。
mkinitcpio 由 Arch Linux 开发者开发,并由社区贡献。请参阅 公共 Git 仓库。
重要的是要注意,在初始 ramdisk 阶段执行各种任务的方式有两种不同的方法
- 基于 Busybox 的初始 ramdisk
- 启动一个 init 脚本,该脚本反过来扫描初始 ramdisk 的文件系统,以查找要执行的脚本(在此上下文中称为运行时 hook)。
- 基于 systemd 的初始 ramdisk
- systemd 已经在初始 ramdisk 阶段的开始时启动。要执行的任务由常规 systemd 单元文件确定。请参阅 systemd 启动过程。
具体变体由 /etc/mkinitcpio.conf
的 HOOKS
数组中 systemd
hook 的存在与否决定。有关更多详细信息,请参阅 #通用 Hook。
安装
安装 mkinitcpio 软件包,它是 linux 软件包的依赖项,因此大多数用户已经安装了它。
高级用户可能希望通过 mkinitcpio-gitAUR 软件包从 Git 安装 mkinitcpio 的最新开发版本。
镜像创建与激活
自动生成
每次安装或升级内核时,pacman hook 都会自动生成一个 .preset 文件,保存在 /etc/mkinitcpio.d/
中。例如,官方稳定 linux 内核软件包的 linux.preset
。预设只是创建初始 ramdisk 镜像所需的信息列表,而不是手动指定各种参数和输出文件的位置。默认情况下,它包含创建两个镜像的指令
- default ramdisk 镜像,按照 mkinitcpio #配置 中指定的指令创建,以及
- fallback ramdisk 镜像,与上面相同,只是在创建过程中跳过了 autodetect hook,因此包含支持大多数系统的全范围模块。
创建预设后,pacman hook 调用 mkinitcpio 脚本,该脚本使用预设中提供的信息生成两个镜像。
手动生成
要手动运行脚本,请参阅 mkinitcpio(8) 手册页以获取说明。特别是,要(重新)生成基于内核软件包提供的预设的 initramfs 镜像,请使用 -p
/--preset
选项,后跟要使用的预设。例如,对于 linux 软件包,使用命令
# mkinitcpio -p linux
要(重新)生成基于所有现有预设的 initramfs 镜像,请使用 -P
/--allpresets
开关。这通常用于在更改全局 #配置 后重新生成所有 initramfs 镜像
# mkinitcpio -P
用户可以使用各种不同的配置创建任意数量的 initramfs 镜像。所需的镜像必须在相应的 引导加载程序 配置文件中指定。
自定义生成
用户可以使用备用配置文件生成镜像。例如,以下命令将根据 /etc/mkinitcpio-custom.conf
中的指示生成初始 ramdisk 镜像,并将其另存为 /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
统一内核镜像
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
选项调用 mkinitcpio 和/或使用包含 ALL_config
的预设,则不考虑它们)。此外,预设定义由内核软件包在 /etc/mkinitcpio.d
目录中提供(例如 /etc/mkinitcpio.d/linux.preset
)。
用户可以修改配置文件中的七个变量,有关更多详细信息,请参阅 mkinitcpio.conf(5) § VARIABLES
MODULES
- 在运行任何启动 hook 之前要加载的内核模块。
BINARIES
- 要包含在 initramfs 镜像中的其他二进制文件。
FILES
- 要包含在 initramfs 镜像中的其他文件。
HOOKS
- Hook 是在初始 ramdisk 中执行的脚本。
COMPRESSION
- 用于压缩 initramfs 镜像。
COMPRESSION_OPTIONS
- 传递给
COMPRESSION
程序的额外参数。强烈建议不要使用此设置。mkinitcpio 将处理压缩程序的特殊要求(例如,将--check=crc32
传递给 xz),并且误用很容易导致系统无法启动。 MODULES_DECOMPRESS
- 是否解压缩可加载的内核模块和固件文件,还是将它们保留在其原始压缩形式。
- 您的系统可能需要的一些 hook,如 lvm2、mdadm_udev 和 encrypt 默认情况下 未 启用。请仔细阅读 #HOOKS 部分以获取说明。
- 版本 36 之前 mkinitcpio 创建的预设文件设置了变量
ALL_config
,这会阻止加载 Drop-in 配置文件。要启用 Drop-in 文件,请注释掉较旧预设文件中的行ALL_config="/etc/mkinitcpio.conf"
。
MODULES
MODULES
数组用于指定在完成任何其他操作之前要加载的模块。
以 ?
结尾的模块如果未找到,则不会抛出错误。这对于自定义内核可能很有用,这些内核在 hook 或配置文件中显式列出的模块中编译。
- 如果使用将在早期用户空间中挂载的树外文件系统(例如,当使用此类文件系统作为根文件系统时),则其模块(例如
reiser4
)必须 添加到MODULES
数组中。 - 当使用 encrypt 或 sd-encrypt hook 时,当目标系统与用于运行 mkinitcpio 的系统不同时,需要将系统启动期间解锁 LUKS 设备所需的键盘模块和/或文件系统添加到
MODULES
数组中。例如,如果您在 ext2 文件系统上使用密钥文件,但在 mkinitcpio 运行时未挂载任何 ext2 文件系统,请添加ext2
。有关更多详细信息,请参阅 dm-crypt/系统配置#cryptkey。 - 如果通过 USB 3 集线器使用键盘,并希望使用它来解锁 LUKS 设备,请添加
usbhid xhci_hcd
。 - 如果使用连接到扩展坞的显示器,您可能需要为您的显卡添加模块以使 initrd 输出可见(例如,大多数 Intel 显卡的
i915
)。
BINARIES 和 FILES
这些选项允许用户向镜像添加文件。BINARIES
和 FILES
都在 hook 运行之前添加,并且可以用于覆盖 hook 使用或提供的文件。BINARIES
在标准 PATH
中自动定位,并进行依赖项解析,这意味着任何所需的库也将被添加。FILES
按原样添加。例如
FILES=(/etc/modprobe.d/modprobe.conf)
BINARIES=(kexec)
请注意,由于 BINARIES
和 FILES
都是 Bash 数组,因此可以添加多个条目,并用空格分隔。
HOOKS
HOOKS
数组是文件中最重要的设置。Hook 是描述将添加到镜像中的内容的脚本。对于某些 hook,它们还将包含一个运行时组件,该组件提供额外的行为,例如启动守护程序或组装堆叠块设备。Hook 通过其名称引用,并按照它们在配置文件的 HOOKS
数组中存在的顺序执行。
默认的 HOOKS
设置对于大多数简单的单磁盘设置应该足够了。对于堆叠或多块设备(如 LVM、RAID 或 dm-crypt)的根设备,请参阅相应的 Wiki 页面以获取进一步必要的配置。
构建 Hook
构建 hook 位于 /usr/lib/initcpio/install/
中,自定义构建 hook 可以放置在 /etc/initcpio/install/
中。这些文件在 mkinitcpio 运行时由 bash shell 导入,应包含两个函数:build
和 help
。build
函数描述将添加到镜像中的模块、文件和二进制文件。由 mkinitcpio(8) 文档化的 API 有助于添加这些项目。help
函数输出 hook 完成的功能的描述。
有关所有可用 hook 的列表
$ mkinitcpio -L
使用 mkinitcpio 的 -H
/--hookhelp
选项输出特定 hook 的帮助,例如
$ mkinitcpio -H udev
运行时 Hook
运行时 hook 位于 /usr/lib/initcpio/hooks/
中,自定义运行时 hook 可以放置在 /etc/initcpio/hooks/
中。对于任何运行时 hook,都应该始终有一个同名的构建 hook,它调用 add_runscript
将运行时 hook 添加到镜像中。这些文件在早期用户空间期间由 busybox ash shell 导入。除了清理 hook 外,它们将始终按照 HOOKS
设置中列出的顺序运行。运行时 hook 可能包含多个函数
run_earlyhook
:一旦 API 文件系统被挂载并且内核命令行被解析,就会运行此名称的函数。这通常是启动早期启动过程所需的其他守护程序(例如 udev)的位置。
run_hook
:此名称的函数在早期 hook 之后不久运行。这是最常见的 hook 点,堆叠块设备的组装等操作应在此处进行。
run_latehook
:此名称的函数在根设备挂载后运行。这应该谨慎使用,用于进一步设置根设备,或用于挂载其他文件系统,例如 /usr
。
run_cleanuphook
:此名称的函数尽可能晚地运行,并且以与配置文件中 HOOKS
数组中列出的顺序相反的顺序运行。这些 hook 应用于任何最后一分钟的清理,例如关闭早期 hook 启动的任何守护程序。
通用 Hook
下表列出了通用 hook 及其如何影响镜像创建和运行时。请注意,此表并不完整,因为软件包可以提供自定义 hook。
busybox init | systemd init | 构建 Hook | 运行时 Hook(仅限 busybox init) |
---|---|---|---|
base | 可选 | 设置所有初始目录并安装基本实用程序和库。始终将此 hook 作为第一个 hook 保留,除非您知道自己在做什么,因为它在不使用 systemd hook 时提供关键的 busybox init。 当使用 systemd hook 时可选,因为它仅提供 busybox 恢复 shell。 注意: 由于 initramfs 中的 root 帐户是 锁定的,因此恢复 shell 不可用。请参阅 archlinux/mkinitcpio/mkinitcpio#205。
|
– |
udev | systemd | 将 udevd、udevadm 和 udev 规则的小子集添加到您的镜像中。 | 启动 udev 守护程序并处理来自内核的 uevent;创建设备节点。由于它简化了启动过程,无需用户显式指定必要的模块,因此建议使用它。 |
usr | 添加对单独分区上的 /usr 的支持。有关详细信息,请参阅 #/usr 作为单独分区。 |
在实际根目录挂载后挂载 /usr 分区。 | |
resume | 添加 lzo 和 lz4 内核模块,以允许在使用编译时默认值以外的休眠镜像压缩算法时恢复。添加 systemd-hibernate-resume(8) 二进制文件以支持从通过 HibernateLocation UEFI 变量指定的休眠镜像恢复。 |
尝试从“挂起到磁盘”状态恢复。有关进一步配置,请参阅 休眠。 | |
btrfs | – | 设置启用 Btrfs 以使用带有 Btrfs 的多个设备所需的模块。您需要安装 btrfs-progs 才能使用此 hook。此 hook 不是在单个设备上使用 Btrfs 所必需的,filesystems hook 就足够了。 |
当 udev hook 或 systemd hook 不存在时,运行 btrfs device scan 以组装多设备 Btrfs 根文件系统。btrfs-progs 软件包是此 hook 所必需的。 |
autodetect | 通过从 sysfs 扫描创建模块白名单,将您的 initramfs 缩小到更小的尺寸。请务必验证包含的模块是否正确,并且没有遗漏任何模块。此 hook 必须在其他子系统 hook 之前运行,才能利用自动检测。在 'autodetect' 之前放置的任何 hook 都将完整安装。 | – | |
microcode | 在未压缩的 initramfs 镜像前添加 Intel 和 AMD 处理器的早期 微码 更新文件。如果 /usr/lib/firmware/amd-ucode/ 和 /usr/lib/firmware/intel-ucode/ 中的微码文件可用,则使用它们,否则提取 /boot/amd-ucode.img 和 /boot/intel-ucode.img 。如果 autodetect hook 在此 hook 之前运行,它将仅添加构建镜像的系统处理器的早期微码更新文件。 此 hook 的使用取代了现在已弃用的 --microcode 标志和预设文件中的 microcode 选项。这也允许您从启动配置中删除微码 initrd 行,因为它们现在与主 initramfs 镜像打包在一起。 |
– | |
modconf | 包含来自 /etc/modprobe.d/ 和 /usr/lib/modprobe.d/ 的 modprobe 配置文件。 |
– | |
kms | 添加 GPU 模块以提供 早期 KMS 启动。此外,还添加了一些笔记本电脑 LCD 面板中内置的隐私屏幕所需的模块。 | – | |
keyboard | 添加键盘设备所需的模块。如果您有 USB 或串行键盘并且在早期用户空间中需要它(用于输入加密密码或用于交互式 shell),请使用此 hook。作为副作用,也可能会添加一些非键盘输入设备的模块,但这不应依赖。 注意: 对于使用不同硬件配置启动的系统(例如,带有外部键盘与内部键盘的笔记本电脑或 无头系统),此 hook 需要放置在 autodetect 之前,以便能够在启动时使用键盘,例如,在使用
encrypt hook 时解锁加密设备。 |
– | |
keymap | sd-vconsole | 将来自 /etc/vconsole.conf 的指定 控制台键盘映射 添加到 initramfs。如果您使用 系统加密,尤其是全盘加密,请确保将其添加到 encrypt hook 之前。 |
在早期用户空间期间从 /etc/vconsole.conf 加载指定的控制台键盘映射。 |
consolefont | 将来自 /etc/vconsole.conf 的指定 控制台字体 添加到 initramfs。 |
在早期用户空间期间从 /etc/vconsole.conf 加载指定的控制台字体。 | |
block | 添加块设备模块。如果 autodetect hook 在此 hook 之前运行,它将仅添加系统上使用的块设备的模块。例外情况是 ahci 、sd_mod 、usb_storage 、uas 、mmc_block 、nvme 、virtio_scsi 和 virtio_blk 模块,它们将始终无条件添加。 |
– | |
net | 未实现 | 添加网络设备所需的模块。您必须安装 mkinitcpio-nfs-utils 才能使用此 hook,有关详细信息,请参阅 #使用 net。 | 为基于 NFS 的根文件系统提供处理。 |
dmraid | ? | 为 fakeRAID 根设备提供支持。您必须安装 dmraid 才能使用此 hook。请注意,如果您的控制器支持,则首选将 mdadm 与 fakeRAID 的 mdadm_udev hook 一起使用。有关详细信息,请参阅 #使用 RAID。 | 使用 dmraid 定位和组装 fakeRAID 块设备。 |
mdadm_udev | 提供通过 udev 组装 RAID 阵列的支持。您必须安装 mdadm 才能使用此 hook。有关详细信息,请参阅 RAID#配置 mkinitcpio。 | – | |
encrypt | sd-encrypt | 将 dm_crypt 内核模块和 cryptsetup 工具添加到镜像中。您必须安装 cryptsetup 才能使用此 hook。注意: 请注意上面 keyboard hook 的备注,以便在启动期间解锁加密设备,以及/或当您使用文件解锁时 #MODULES 中的文件系统备注。 |
检测并解锁加密的根分区。有关进一步配置,请参阅 #运行时自定义。 对于 sd-encrypt,请参阅 dm-crypt/系统配置#使用 systemd-cryptsetup-generator。 |
lvm2 | 将设备映射器内核模块和 lvm 工具添加到镜像中。您必须安装 lvm2 才能使用此 hook。如果您的根文件系统位于 LVM 上,则这是必需的。 |
– | |
filesystems | 这会将必要的文件系统模块包含到您的镜像中。除非您在 MODULES 中指定您的文件系统模块,否则此 hook 是必需的。 |
– | |
fsck | 添加 fsck 二进制文件和文件系统特定的帮助程序,以允许在挂载之前针对您的根设备(和 /usr ,如果单独分区)运行 fsck。如果在 autodetect hook 之后添加,则只会添加特定于您的根文件系统的帮助程序。强烈建议使用此 hook,并且对于单独的 /usr 分区是必需的。强烈建议,如果您包含此 hook,您还应包含任何必要的模块,以确保您的键盘在早期用户空间中可以工作。此 hook 的使用需要将 rw 参数设置在 内核命令行 上(讨论)。有关更多详细信息,请参阅 fsck#启动时检查。 |
– | |
acpi_override | 将 /usr/initcpio/acpi_override/ 和 /etc/initcpio/acpi_override/ 中找到的 ACPI 机器语言 (.aml) 文件添加到早期的未压缩 initramfs 镜像,以便内核可以在启动早期覆盖 ACPI 表(例如 DSDT)。[1] |
– |
后处理 Hook
后处理 hook 是位于 /usr/lib/initcpio/post/
(软件包提供的 hook)和 /etc/initcpio/post/
(自定义 hook)中的可执行文件或 shell 脚本。这些文件在镜像(重新)生成后执行,以执行签名等其他任务。
以下参数按此顺序传递给每个可执行文件
- 使用的 内核(在某些情况下可能为空);
- 生成的 initramfs 镜像;
- (可选)生成的 统一内核镜像。
此外,还设置了以下环境变量——KERNELVERSION
完整内核版本,KERNELDESTINATION
内核应位于其上以便启动的默认位置。
COMPRESSION
内核支持 initramfs 压缩的几种格式:gzip、bzip2、lzma (xz)、xz、lzo (lzop)、lz4 和 zstd。默认情况下,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
选项非常有效。但是,RAM 有限的系统可能无法使用此选项解压缩 initramfs。也可能需要 -v
选项以查看 initramfs 生成期间的详细信息。例如
COMPRESSION="zstd" COMPRESSION_OPTIONS=(-v -5 --long)
通过使用 xz 和 -9e
压缩级别,以及解压缩可加载内核模块和固件,可以实现最高但最慢的压缩
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 使用率,这对 RAM 有限或 CPU 较弱的系统产生负面影响,因为内核将花费更多时间来解压缩整个 initramfs 镜像,而不是在加载时解压缩各个模块和固件。
运行时自定义
运行时配置选项可以通过内核命令行传递给 init
和某些 hook。内核命令行参数通常由引导加载程序提供。下面讨论的选项可以附加到内核命令行以更改默认行为。有关更多信息,请参阅 内核参数 和 Arch 启动过程。
来自 base hook 的 init
root=
- 这是内核命令行上指定的最重要的参数,因为它决定了哪个设备将作为您的正确根设备挂载。mkinitcpio 足够灵活,可以支持各种格式;有关示例,请参阅 持久块设备命名#内核参数。
init
的默认行为。有关详细信息,请参阅 /usr/lib/initcpio/init
。当使用 systemd
hook 时,它们将不起作用,因为来自 base
hook 的 init
已被替换。break
- 如果指定了
break
或break=premount
,init
将暂停启动过程(在加载 hook 之后,但在挂载根文件系统之前)并启动一个交互式 shell,可用于故障排除。通过指定break=postmount
,可以在根目录挂载后启动此 shell。从 shell 退出后,正常启动将继续。
disablehooks=
- 通过添加
disablehooks=hook1[,hook2,...]
在运行时禁用 hook。例如disablehooks=resume
earlymodules=
- 通过指定要提前加载的模块,使用
earlymodules=mod1[,mod2,...]
更改模块的加载顺序。(例如,这可以用于确保多个网络接口的正确顺序。)
有关其他参数,请参阅 启动调试 和 mkinitcpio(8)。
使用 RAID
请参阅 RAID#配置 mkinitcpio。
使用 net
必需软件包
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=off
或 ip=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.
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 hooks。
使用加密根目录
如果使用加密根目录,请参阅 dm-crypt/系统配置#mkinitcpio,以获取有关要包含哪些 hooks 的详细信息。
/usr 作为单独的分区
如果您将 /usr
保留为单独的分区,则必须遵守以下要求
- 添加
fsck
hook,在/etc/fstab
中将/usr
标记为passno
为2
,以便在启动时检查分区。虽然建议所有人这样做,但如果您希望在启动时 fsck 您的/usr
分区,则这是强制性的。没有此 hook,/usr
将永远不会被 fsck。 - 如果未使用 systemd hook,请添加
usr
hook。这将在根目录挂载后挂载/usr
分区。
技巧和窍门
禁用回退 initramfs 生成
可以禁用回退镜像的生成
- 将
/etc/mkinitcpio.d/
中各自的 .preset 文件中的PRESETS=('default' 'fallback')
行更改为PRESETS=('default')
。 - 删除
/boot/
中的回退 initramfs 镜像。 - 更新您的引导加载程序配置。
故障排除
提取镜像
如果您对 initramfs 镜像内部的内容感到好奇,可以提取它并查看其中的文件。
initramfs 镜像是一个 SVR4 CPIO 存档,通过 find
和 bsdcpio
命令生成,可以选择使用内核理解的压缩方案进行压缩。有关压缩方案的更多信息,请参阅 #压缩。
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 必须已挂载” 但实际上已经挂载了
mkinitcpio 用于确定 /dev
是否已挂载的测试是查看 /dev/fd/
是否存在。如果其他一切看起来都正常,则可以通过以下方式手动“创建”它
# ln -s /proc/self/fd /dev/
(显然,/proc
也必须已挂载。mkinitcpio 无论如何都需要它,那是它将要检查的下一件事。)
模块 XXXX 可能缺少固件
在内核更新后重建 initramfs 时,您可能会收到警告
==> WARNING: Possibly missing firmware for module: 'module_name'
如果在生成默认 initramfs 镜像时出现这些消息,那么正如警告所说,可能需要安装额外的固件。大多数常见的固件文件可以通过安装 linux-firmware 软件包来获取。有关提供固件的其他软件包,请参阅下表或尝试在官方仓库或 AUR 中搜索模块名称。
否则,如果消息仅在生成回退 initramfs 镜像时出现,您有以下选项
- 如果您知道您不使用受影响的硬件,则可以安全地忽略警告。
- 如果您想抑制警告,可以安装缺少的固件。元软件包 mkinitcpio-firmwareAUR 包含大多数可选固件。或者,手动安装所需的软件包
模块 软件包 aic94xx aic94xx-firmwareAUR ast ast-firmwareAUR bfa linux-firmware-qlogic bnx2x linux-firmware-bnx2x liquidio linux-firmware-liquidio mlxsw_spectrum linux-firmware-mellanox nfp linux-firmware-nfp qat_420xx 固件尚不可用。请参阅 [2] qed linux-firmware-qlogic qla1280 linux-firmware-qlogic qla2xxx linux-firmware-qlogic wd719x wd719x-firmwareAUR xhci_pci 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
数组。[3]
标准救援程序
如果初始 ram-disk 不正确,系统通常无法启动。因此,请遵循如下系统救援程序
在一台机器上启动成功,在另一台机器上启动失败
mkinitcpio 的 autodetect
hook 在主 initramfs 中过滤掉不需要的 内核模块,扫描 /sys
以及运行时加载的模块。如果您将 /boot
目录传输到另一台机器,并且启动序列在早期用户空间期间失败,则可能是因为由于缺少内核模块而未检测到新硬件。请注意,USB 2.0 和 3.0 需要不同的内核模块。
要修复此问题,首先尝试从您的 引导加载程序 中选择回退镜像,因为它不受 autodetect
过滤。启动后,在新机器上运行 mkinitcpio 以使用正确的模块重建主镜像。如果回退镜像失败,请尝试启动到 Arch Linux live CD/USB,chroot 进入安装,并在新机器上运行 mkinitcpio。作为最后的手段,尝试手动将模块添加到 initramfs。
另请参阅
- Linux 内核文档关于 initramfs,“什么是 rootfs?”
- Linux 内核文档关于 initrd
- Wikipedia 文章关于 initrd