mkinitcpio (简体中文) - ArchWiki

Jump to content

翻译状态：本文是 Mkinitcpio 的翻译。上次翻译日期：2022-08-21。如果英文版本有所更改，则您可以帮助同步翻译。

相关文章

- systemd
- Kernel modules
- Minimal initramfs
- Boot debugging

mkinitcpio 是一个创建 initramfs 的 bash 脚本。来自 mkinitcpio(8)帮助页面。

  初始内存盘本质上是一个很小的运行环境（早期用户空间），用于加载一些核心模块，并在 `init` 接管启动过程之前做必要的准备。有了这个环境，才能支持加密根文件系统、RAID上的根文件系统等高级功能。mkinitcpio 支持自定义的钩子扩展、运行时自动检测以及其他功能。

从前，内核在启动过程早期（挂载根目录和移交控制权给`init`之前）处理一切硬件的检测和初始化。然而，但随着技术的演进，这种做法变得十分繁琐。

如今，根文件系统可能位于各种硬件上，如SCSI设备、SATA设备、U盘，而这些硬件受控于形形色色的厂家所提供的五花八门的驱动之下。另外，根系统可以加密、压缩，可存放在RAID阵列中，或者一个逻辑卷组上。为了简化这复杂的过程，可以把管理权转入一个用户空间：初始化内存盘。

另见：/dev/brain0 » Blog Archive » Early Userspace in Arch Linux。 mkinitcpio 从Arch Linux开发者和社区贡献中得到了进一步发展。 另见 public Git repository.

## 安装

安装 软件包 mkinitcpio。这个软件包是 linux 软件包的依赖，应该已经自动安装了。高级用户可以从mkinitcpio-gitAUR 获取 mkinitcpio 的最新开发版本.

注意： 若要使用git开发版本，强烈建议同时加入arch-projects 邮件列表！

## 创建和启用镜像

### 自动匹配生成

每次安装或升级内核，pacman钩子pacman hook自动产生.preset文件，保存在`/etc/mkinitcpio.d/`。例如：`linux.preset`文件是官方稳定版linux包产生的。一个preset是简明的创建初始化内存镜像需要的列表信息，以取代手动明确各种参数和输出文件位置。默认mkinitcpio都会创建两个内存盘镜像：

1. 默认镜像`/boot/initramfs-linux.img`按照mkinitcpio #配置明确的指令创造而来。
2. fallback镜像`/boot/initramfs-linux-fallback.img`。产生过程和上面一样。唯一区别，就是创建时跳过了autodetect钩子扩展，因而它包含全范围内更多的内核模块，可以支持大部分系统。（ps:原文删除这个陈述，感觉有些用处autodetect扩展会探测硬件信息，针对硬件向镜像添加需要的模块，因此缩小了镜像。)

生成proset之后，pacman钩子会利用proset提供的信息调用 mkinitcpio 脚本创建上面的两个镜像。

注意： .preset 在内核更新后会被用来自动生成内存镜像，编辑它们要小心仔细。

### 手动生成

手动运行脚本，参照mkinitcpio(8) 帮助页面获得指引。尤其是利用内核包生成（重新生成）预设，使用`-p`/`--preset`选项按照预设生成镜像。例如 为 linux 包生成镜像，使用这个命令：

    # mkinitcpio -p linux

利用`-P`/`--allpresets`选项，根据所有现存的预设文件生成镜像。典型的用法是当全局设置#配置变化后用此法生成全部的内存镜像：

    # mkinitcpio -P

可以按照不同的配置文件创建任意数量的内存镜像。想要引导加载的镜像必须在相应的引导记录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

### unified kernel image 统一的内核镜像

按照31版本, mkinitpcio 也能够产生 unified kernel image。

## 配置

mkinitcpio的主配置文件是`/etc/mkinitcpio.conf`。此外，内核软件包的预配置文件位于`/etc/mkinitcpio.d`（例如：`/etc/mkinitcpio.d/linux.preset`）。

用户可以编辑配置文件中的六个变量，参见mkinitcpio.conf(5)获得更多细节：

`MODULES`
  在钩子扩展运行前需要加载的内核模块。
`BINARIES`
  内存盘镜像中包含的额外的二进制文件（一般是可执行的命令）。
`FILES`
  内存盘镜像中包含的其他文件。
`HOOKS`
  要执行的钩子扩展，它是在生成镜像是执行的脚本。
`COMPRESSION`
  内存盘镜像的压缩方式。
`COMPRESSION_OPTIONS`
  传递给压缩工具的额外参数，强烈不建议使用，mkinitcpio 可以自动根据压缩算法传递需要的参数(例如对 xz 传递 `--check=crc32` to xz), 手动设置了错误的参数可能导致系统无法启动。

注意：

- 一些系统需要的钩子像 lvm2, mdadm_udev, and encrypt 默认 不是开启的 。参见 #钩子(HOOKS) 仔细遵循指示。
- 存在多个硬盘控制器使用相同的节点名字，但是拥有不同的内核模块（例如，两个SCSI/SATA控制器或2个IDE控制器）应该使用 持久化设备命名persistent block device naming 保证正确的设备被挂载。否则在两次系统启动时根系统的位置可能改变导致内核崩溃。

### 模块（MODULES）

`MODULES`数列指定了启动过程最开始时早于一切事情就要加载的模块。

如果模块名称前加上一个`?`问号，那么即使系统无法找到该模块也不会报错。对于自己编译的内核，其中内置了某些模块在，这些模块在钩子或配置文件中显式的列出来时，该功能可能有用。

注意：

- 如果使用reiser4，该模块必须放入`MODULES`数列中。
- 当使用encrypt or sd-encrypt 钩子时,目标系统和运行mkinitcpio系统不同时，键盘模块和/或启动系统期间需要解锁LUKS设备的文件系统模块加入 `MODULES` 数列。例如，如果需要使用位于一个ext2系统的钥匙文件，但是运行mkinitcpio的系统中ext2文件系统没有被挂载，增加`ext2`。参见 dm-crypt/System configuration#cryptkey 获得更多细节。
- 如果使用USB3接口的键盘，希望用它来解锁LUKS设备。增加`usbhid xhci_hcd`。
- 如果使用显示器连接扩展坞，可能需要加入你的显卡模块使初始化输出信息可见(例如，为大多数英特尔显卡加入 `i915` )。

### 二进制文件和普通文件（BINARIES、FILES）

这两个选项允许用户添加任何文件到镜像中。`BINARIES`、`FILES`数列在钩子运行之前指定了要加入内存盘镜像的文件，可以覆盖钩子扩展提供的文件。`BINARIES`中的二进制文件会自动放入一个标准的`PATH`路径，而且会自动加入可执行文件依赖的函数库。`FILES`中的文件则不进行上述处理，as-is直接原样放入镜像。例如：

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

注意`BINARIES` and `FILES` 是 Bash数列，配置支持多个选项，用空格隔开。

### 钩子(HOOKS)

`HOOKS`设置是此文件中最重要的设置。Hooks 是一系列的小脚本，描述哪些东西需要加入到镜像里面。有些钩子还包含了运行组件，可以提供额外的行特定动作，像启动服务、构建存储栈的块设备等a stacked block device。Hooks 按照配置文件中`HOOKS`项中给出的顺序执行。

默认的`HOOKS`可以满足大部分简单的单硬盘系统。对于堆栈的或多块设备像 LVM, RAID, or dm-crypt 等复杂根分区系统，请查看相应的 Wiki 页面，进行必要的进一步设置。 （英文文档删除下面关于键盘内容，可能是 keyboard 默认加入`HOOKS`，后面的问题不再是问题，出于谨慎我保留了下来） PS/2 键盘用户 : 要在初始化早期阶段使用键盘，请把 keyboard 钩子加入 `HOOKS`. 个别的键盘无法自动检测到 i8042 控制器，出现 `i8042: PNP: No PS/2 controller found. Probing ports directly` 报错信息，导致无法使用键盘，请把 atkbd 加入 `MODULES`.

#### 编译钩子

编译钩子位于`/usr/lib/initcpio/install`，自定义的编译钩子可能位于`/etc/initcpio/install/`。这些文件会在运行 mkinitcpio 时被包含进脚本，应该提供如下两个函数：`build` 和 `help`。`build` 函数描述了需要加入镜像的模块、文件和二进制文件。mkinitcpio(8) 中的记录的 API 帮助添加这些项目。`help` 函数在钩子执行后输出描述信息。

列出可用的钩子列表：

    $ mkinitcpio -L

使用 mkinitcpio 的 `-H`/`--hookhelp` 选项输出对于某一钩子的帮助。例如：

    $ mkinitcpio -H udev

#### 运行时钩子

运行时钩子可以在`/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 基础的初始化, 它不需要运行任何运行时钩子，而是使用systemd单元。

#### 常用钩子

下面是一个常见钩子和它们如何影响镜像的创建以及运行时的次序。注意这个表格是不完整的，因为一些包会提供一些自定义的钩子。

This article or section needs expansion.

Reason: 增加关于`hostdata`, `memdisk`, `sleep` 和`strip`的信息, 找出`dmraid`等是否在 systemd 为基础的镜像中正常工作或被需要。 (Discuss in Talk:Mkinitcpio (简体中文)#Improvements for the Common hooks table and section about systemd hook)

busybox 初始化 | systemd 初始化 | 编译钩子 | 运行时钩子 (仅busybox 初始化)
--- | --- | --- | ---
base | 安装初始化目录结构，安装基本工具及其依赖。除非知道你在做什么，总是保持此钩子为第一个钩子，因为当没有使用systemd钩子时，它提供关键的busybox初始化过程。 当使用systemd钩子时此钩子可选，因为它仅提供busybox恢复shell。 注意： 因为root账户在初始化内存镜像是锁定的，恢复shell是不能用的。locked. 参见 FS#70408. | –
udev | systemd | 增加 udevd, udevadm,和一小套udev规则进镜像。 | 从内核中启动udev守护进程和uevents过程; 创建设备节点。因为不需要用户清晰的明确出必须设备这是简化的引导过程，推荐使用。
usr | 增加支持`/usr` 在独立分区。参见#/usr 放到单独分区 获得更多细节。 | 在挂载真正根分区后挂载 `/usr` 分区 。
resume | – | 试图从"suspend to disk" 状态重新开始。 参见 Hibernation 做进一步设置。
btrfs | – | 设置必备模块能够让Btrfs 支持Btrfs的多设备分区。需要安装 btrfs-progs 开启功能。Btrfs在单设备分区时此钩子不需要。 | 当udev 钩子或systemd不存在时，运行 `btrfs device scan` 组装多设备Btrfs根文件系统。安装btrfs-progs 包使用此钩子。
autodetect | 系统扫描后创建设备白名单从而减少内存镜像的尺寸。确定校验进入的模块正确性和完整性。为了自动侦测发挥作用，必须放在其他子系统钩子之前。放在'autodetect'钩子之前的钩子将会被完整安装。 | –
modconf | 从`/etc/modprobe.d/`和`/usr/lib/modprobe.d/`中包含探测模块配置文件。 | –
block | 加载所有的块设备，以前fw, mmc, pata, sata, scsi, usb, and virtio 钩子分别提供。 | –
net | not implemented | 增加必要网络设备模块。必须安装 mkinitcpio-nfs-utils 包, 参见 #使用 net | 支持NFS为基础的根文件系统。
dmraid | ? | 支持fakeRAID根设备。必须安装 dmraid 包。注意如果你的控制器支持，更好选择是mdadm 联合 mdadm_udev钩子支持fakeRAID根设备。参见 #使用 RAID 磁盘阵列 。 | 使用`dmraid`定位组装fakeRAID块设备。
mdadm_udev | 通过udev支持组装RAID阵列。必须安装 mdadm 包。若在FakeRAID使用这个钩子推荐将 `mdmon` 加入 `BINARIES`. 参见 #使用 RAID 磁盘阵列 。 | –
keyboard | 为键盘设备增加必要的模块。如果USB或串口键盘在早期用户空间起作用加入此钩子（可以输入密码或和shell交互）。有一个副作用，一些非键盘的输入设备也可能加进来，但这并不可靠。此钩子代替老的 usbinput钩子。 注意： 使用不同的硬件配置启动的系统（例如笔记本电脑连接外置键盘和内置键盘或headless systems）时，此钩子需要放在autodetect之前才能在引导中使用键盘，例如使用`encrypt`钩子解密加密设备。 | –
keymap | sd-vconsole | 自`/etc/vconsole.conf`加入特定的 键盘映射keymap(s) 到镜像。在早期用户空间如果使用系统加密, 尤其全盘加密, 此钩子放在`encrypt`钩子之前。
consolefont | 自`/etc/vconsole.conf`中加入特定的 终端字体 到镜像。 | 在早期用户空间自`/etc/vconsole.conf`里，使用特定的终端字体。
encrypt | sd-encrypt | 增加`dm_crypt` 内核模块 和 `cryptsetup` 工具到镜像。 必须安装cryptsetup包。 注意： 启动时反复确认keyboard钩子放在解密设备前面。和/或当使用钥匙文件解锁时，存放钥匙文件的文件系统加入#模块（MODULES） 里。 | 侦测和解锁加密根系统。参见 #运行时配置 。
    sd-encrypt 参见 dm-crypt/System configuration#Using systemd-cryptsetup-generator.
lvm2 | 加入设备映射内核模块和`lvm` 工具到镜像。 必须安装lvm2 包。 如果根系统在LVM这是必须的钩子。 | –
fsck | 增加fsck二进制文件和特定系统帮助文件，允许fsck在挂载前处理根系统（和/usr分区如果有）。如果放在autodetect钩子前仅仅加载的定的帮助文件到根系统。强烈推荐使用此钩子，独立`/usr`分区需要它。强烈建议如果使用的此钩子同时要加入必要模块保证键盘在早期用户空间使用。 使用这个钩子需要在kernel command line内核命令行加入 `rw`参数。(讨论). 参见 fsck#Boot time checking 。 | –
filesystems | 除非在`MODULES`中加入了文件系统，不然此钩子是必须的。 | –

#### 编写钩子扩展

（*最新的英文文档删除了这部分内容，感觉似乎用些用处暂时留了下来。） 一个 initcpio 钩子仅仅是另一段 shell 脚本，它包含了必要的信息指引 mkinitcpio 哪一个可执行文件应该被加载，以及以什么参数被加载。它在某些罕见情况下很有用，比如一些文件需要在用户空间的早期或晚期被加载，而这又没有被其他已经安装的脚本提供。

首先创建实际的脚本：

    /usr/lib/initcpio/install/hook

     #!/bin/bash

     build() {
         add_binary /bin/bash  #/bin/bash is given as an example, you can type your desired executable here
         add_runscript  # will determine the name of the script, and add appropriately from /usr/lib/initcpio/hooks
     }

     help() {
         cat <<HELPEOF
         Line used as help information #Typing mkinitcpio -H hook will display this information
     HELPEOF
     }

然后创建这个实际的钩子：

    /usr/lib/initcpio/hooks/hook

     run_hook ()
     {
         msg -n ":: This is an example hook"
         bash #your executable example
         msg "done."
     }

注意： 没有必要为这两个脚本设定可执行权限，也不建议这样做。

现在编辑 `/etc/mkinitcpio.conf` 来包含你的自定义钩子。你也可在 `/etc/rc.sysinit` 包含脚本来在用户空间的后期加载。

### 压缩方式(COMPRESSION)

内核支持几种initramfs的压缩方式 - gzip, bzip2, lzma, xz, lzo, lz4 and zstd。mkinitcpio默认使用zstd压缩镜像，注意zstd运行的多线程模式（使用了`-T0`选项，以侦测到内核数量作为线程数量。）

系统中的 `mkinitcpio.conf` 已经注释掉了各种 `COMPRESSION` 选项，要使用某个压缩方式，请取消前面的注释，并确认安装了相应的压缩工具包。不指定 `COMPRESSION` 选项会使用 zstd 压缩的 initramfs 文件。想要创建一个未压缩的镜像，在配置中指定`COMPRESSION=cat` 或者在命令行使用 `-z cat`。

Template:小技巧

### 压缩选项(COMPRESSION_OPTIONS)

还有一些额外的标准可以传递到 `COMPRESSION` 指定的程序，例如：

    COMPRESSION_OPTIONS='-9'

注意： 这个选项可以留空， mkinitcpio 会确保任何支持的压缩方法有必要的标志来产生一个可以工作的镜像。 另一方面，使用错误的参数选项可能导致内核不能引导，因为错误参数导致内核不能解压生成的压缩档。

## 运行时配置

This article or section needs expansion.

Reason: 哪个选项可以在 `systemd` 钩子工作， 哪个只能在 `base`-only? (Discuss in Talk:Mkinitcpio (简体中文))

。

运行时配置选项可以通过内核命令行传递到 `init` 以及某些钩子。内核命令行参数通常是由启动引导器提供。下面讨论的参数可以附加到内核命令行以改变默认行为。参见 Arch 启动过程和Kernel parameters以获取更多信息。

### 从基本钩子启动

`root`
  这是内核命令行中指定的最重要的参数，因为它决定了哪一个设备会被挂载为你的正确的 root 设备。mkinitcpio 可以灵活的允许不同的格式，例如：

    root=/dev/sda1                                                # /dev 节点
    root=LABEL=CorsairF80                                         # 卷标
    root=UUID=ea1c4959-406c-45d0-a144-912f4e86b207                # UUID
    root=PARTUUID=14420948-2cea-4de7-b042-40f67c618660            # GPT partition UUID

注意： 下面的选项改变了 `init` 在 initramfs 环境中的默认行为。参见 `/lib/initcpio/init` 获取更多信息。当`systemd`钩子作用是，这些参数不起作用，既然来自`base`钩子的 `init` 被取代了。（正如上面的疑问参数该怎么写？）

`break`
  如果`break` 或者 `break=premount` 被指定，`init` 暂停启动过程(在加载钩子之后，但是在挂载根文件系统之前) 然后启动一个交互的 shell，可以用来解决问题。这个 shell 可以在root被指定的`break=postmount`挂载之后启动。正常的启动过程可以在退出这个 shell 之后继续。

`disablehooks`
  在运行时可以通过添加 `disablehooks=hook1{,hook2,...}` 禁用某些钩子。例如

      disablehooks=resume

`earlymodules`
  改变模块加载的顺序。可以通过 `earlymodules=mod1{,mod2,...}` 指定一些模块提前加载。 (例如，这可以用来确保多个网络接口的正确顺序。)

参见: GRUB 和 init 调试和 mkinitcpio(8)。

### 使用 RAID 磁盘阵列

参见 RAID#Configure mkinitcpio。

### 使用 net

警告： NFSv4 仍然不被支持 FS#28287。

必须的包

`net` 需要 mkinitcpio-nfs-utils 包。

内核参数

    内核文档包含最新的信息和清晰的说明。

ip=

这个参数告诉内核怎样生成设备IP地址和怎样安装路由表。它占据9列参数： `ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>:<ntp0-ip>`。

如果这些参数在内核命名行为缺失，所有区域被认为是空白。默认参数在 kernel documentation 应用。通常这就意味这内核利用自动配置表来配置。

    <autoconf> 参数单独作为 ip 的值出现 (没有上面提及的: 分割的字符串)。如果值是 ip=off 或 ip=none, 不执行自动配置，否则会执行自动配置。最常见的是ip=dhcp.

参数进一步扩展，参见 kernel documentation.

例子：

     ip=127.0.0.1:::::lo:none  --> 启用 loopback 界面。
     ip=192.168.1.1:::::eth2:none --> 启用静态 eth2 界面
     ip=:::::eth0:dhcp --> 为eth0启用dhcp。

注意： 确认使用内核设备命名 (例如 eth0) 作为 `<device>` 参数, 不要使用 Network configuration#Network interfaces 命名 (例如 enp2s0) 因为这个不起作用。

BOOTIF= 使用多个网卡的时候，此参数可以指定要使用网卡的 Mac 地址。在接口号可能变化或与 IPAPPEND 2 、IPAPPEND 3 选项共用时比较有用。默认使用 eth0.

示例：

    BOOTIF=01-A1-B2-C3-D4-E5-F6  # 注意前缀加"01-" 并且字母要大写。

nfsroot=

如果命令行中没有给出 `nfsroot` 参数，那么默认的 `/tftpboot/%s` 会被使用。

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

运行`mkinitcpio -H net` 查看参数详细解释。

### 使用 lvm

如果你的根分区在 LVM文件系统中, 参见 Install Arch Linux on LVM#Adding mkinitcpio hooks.

### 使用加密根目录

如果使用 加密 root，请参考 Dm-crypt/System configuration#mkinitcpio。

### /usr 放到单独分区

如果将 /usr 放在单独分区，必须满足：

- 添加 `fsck` 钩子, `/usr`在`/etc/fstab`分区表中的`passno` 参数列为设置为`2` 以便启动时检查该分区。作为常规推荐 如果想要`/usr`分区可以在启动是被检查，以上设置是中肯的。没有这个钩子 `/usr` 永远不能被检查。

- 如果没使用systemd钩子那么增加`usr`钩子。这样将会在挂载根系统后挂载`/usr` 分区。

## 疑难解答

### 解压缩镜像

如果你对 initrd 镜像的内容感到好奇，你可以解压缩它然后看看里面的文件。

initrd 镜像是一个 SVR4 CPIO 压缩包，通过 `find` 和 `bsdcpio` 命令生成，利用可被内核理解的压缩方式被有选择的压缩，参考#压缩方式(COMPRESSION)。

mkinitcpio 包含了一个叫做 lsinitcpio(1) 的工具，可以列出和/或解压缩出 initramfs 镜像的内容。

你可以用下面的命令列出镜像中的文件：

    $ lsinitcpio /boot/initramfs-linux.img

然后全部解压缩到当前文件夹：

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

你也可以用更对人类友好的方式列出镜像中的重要的部分：

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

### 重新压缩解压之后修改过的镜像

警告： 我保留旧的翻译为斜体加黑

在按照上面的方法解压了一个镜像并且进行了修改之后，你可以通过以下的方法得到重新压缩它所需要的命令。按照下面的例子修改 `/usr/bin/mkinitcpio` 中的这一行 (line 531 in mkinitcpio v20-1.)：

    #MKINITCPIO_PROCESS_PRESET=1 "$0" "${preset_cmd[@]}"
    MKINITCPIO_PROCESS_PRESET=1 /usr/bin/bash -x "$0" "${preset_cmd[@]}"

然后用常见的参数运行 `mkinitcpio` (一般来说是 `mkinitcpio -p linux`), 大约在最后的20行你会看见类似下面的一些输出:

    + find -mindepth 1 -printf '%P\0'
    + LANG=C
    + bsdcpio -0 -o -H newc --quiet
    + gzip

它们代表你所需要运行的命令，比如像这样:

    # find -mindepth 1 -printf '%P\0' | LANG=C bsdcpio -0 -o -H newc --quiet | gzip > /boot/initramfs-linux.imgBold text

警告： （下面是新的翻译，我没理解如何激活这个功能？英文wiki就讲了这么多，请老鸟补充详细。所以我保留上面的翻译）

激活`/usr/bin/mkinitcpio`脚本的 `build_image` 功能使用此参数（我没理解如何激活这个功能？请补充详细。）：

    build_image outfile compression

将会产生一个拥有`build_image`功能的新脚本，用上面的参数运行它（outfile输出文件名字，compression压缩工具），将会把当前目录下的内容压缩到一个名字为`outfile`的新文件里。

警告： 建议在运行上面的命令产生一个新的`/boot/initramfs-linux.img`之前把现有的镜像重命名作为备份，以便情况不妙时有后悔药吃。如果因为失误导致系统无法启动，你需要用fallback镜像或者boot CD启动，然后运行mkinitcpio来overwrite掉之前做的更改，或者你自己修好它然后重新压缩镜像。

### "/dev must be mounted" when it already is

mkinitcpio使用这个检测通过判断`/dev/fd/` 是否存在来判断`/dev`是否被挂载。如果其他一切看起来都很好，可以通过以下方式手动“创建”：

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

(显然, `/proc` 必须被安装. mkinitcpio 无论如何要求这样,指示它要检测的下一件事。)

### Possibly missing firmware for module XXXX

当内核更新后，镜像initramfs被重新构建时，你可能得到以下警告：

    ==> WARNING: Possibly missing firmware for module: wd719x
    ==> WARNING: Possibly missing firmware for module: aic94xx
    ==> WARNING: Possibly missing firmware for module: xhci_pci

如果产生 default镜像时出现这些或相近的信息，那么按照警告要求安装额外的被需要的固件firmware。绝大部分固件firmware通过 install安装 linux-firmware包获得。其他提供firmware的包可以查看下表或在 official repositories 或 AUR 中搜索固件模块名字。

除此以外，警告信息只出现在 fallback 镜像生成时，可以按照下面的建议来：

- 如果不需要使用缺失模块的硬件，可以安全的忽略这些警告。
- 如果想要消除这些警告，安装缺失的固件firmware，聚合包mkinitcpio-firmwareAUR 包括绝大部分可选的固件（firmware）。 相应的可以手工安装需要的包：

  模块 | 包
  --- | ---
  aic94xx | aic94xx-firmwareAUR
  bfa | linux-firmware-qlogic
  bnx2x | linux-firmware-bnx2x
  liquidio | linux-firmware-liquidio
  mlxsw_spectrum | linux-firmware-mellanox
  nfp | linux-firmware-nfp
  qat_4xxx | 固件Firmware 已经不可用。
  qed | linux-firmware-qlogic
  qla1280 | linux-firmware-qlogic
  qla2xxx | linux-firmware-qlogic
  wd719x | wd719x-firmwareAUR
  xhci_pci | upd72020x-fwAUR

- 如果想去掉警告，但不想浪费磁盘空间在不需要的固件包上，可以禁止fallback 镜像的生成：
  1. 在所有位于`/etc/mkinitcpio.d/`中的 .preset 文件中修改 `PRESETS=('default' 'fallback')` 行，为 `PRESETS=('default')` 。
  2. 移除fallback镜像： `# rm /boot/*-fallback.img`。
  3. 重新生成引导记录 (例如，对于 GRUB: `# grub-mkconfig -o /boot/grub/grub.cfg`)。

  警告： 如果default镜像启动失败，禁止 fallback 镜像生成将会失去另外一个引导进入系统的选项。进行此操作前，确认拥有可引导的installation medium 作为急救模式。

### No PS/2 控制器被发现

在一些主板（主要是古代的但是也有一些新的主板）， i8042 控制器不能被自动侦测到。这很罕见，但是一些人确定没有键盘使用。 可以提前侦测到这种情况。PS/2 接口得到 `i8042: PNP: No PS/2 controller found. Probing ports directly` 信息，加 atkbd 到 `MODULES` 数列。

### 标准急救过程

使用不正确的初始化内存镜像盘经常出现不可引导。因此遵守以下的系统急救过程：

#### 在一台机器引导成功，但在另一台引导失败

在主要镜像 initramfs 扫描 `/sys` 时 mkinitcpio的 `autodetect` 钩子 过滤掉了 kernel modules ，这些模块在启动被调用。 如果转移`/boot` 目录到其他机器，在早期用户空间造成启动失败，原因是新的硬件由于缺失内核模块不能被侦测到。注意USB 2.0 和 3.0 需要不同的模块。

修正这个缺陷，首先试着从引导记录bootloader 中选择 fallback 镜像 ，因为这个镜像不使用`autodetect`过滤模块。 一旦引导成功，在新机器上运行mkinitcpio用正确的模块重建主要镜像。如果fallback镜像失败，试着用 Arch Linux live CD/USB，使用 arch-chroot 进入系统中, 在新机器上运行 mkinitcpio 。最后的手段，手工增加模块到[#MODULES|手动]]镜像中。

## 参考资料

- Linux Kernel documentation on initramfs, "What is rootfs?"
- Linux Kernel documentation on initrd
- Wikipedia article on initrd

Categories:

- Boot process (简体中文)
- Kernel (简体中文)

Hidden category:

- Pages or sections flagged with Template:Expansion