mkinitcpio

来自 Arch Linux 中文维基

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

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

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

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

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

值得注意的是,initial ramdisk 阶段的各种任务有两种不同的执行方式:

基于 Busybox 的初始化内存镜像
启动一个 init 脚本,该脚本依次扫描 initial ramdisk 的文件系统以查找要执行的脚本(在此上下文中称为运行时挂钩)。
基于 systemd 的初始化内存镜像
systemd 已在 initial ramdisk 阶段开始时启动。要执行的任务由常规的 systemd 单元文件确定。请参阅 systemd bootup process

选择哪种方式由 /etc/mkinitcpio.confHOOKS 数组中是否存在 systemd 钩子决定的。更多细节请参阅 #常用钩子

安装[编辑 | 编辑源代码]

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

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

创建和启用镜像[编辑 | 编辑源代码]

自动匹配生成[编辑 | 编辑源代码]

每次安装或升级内核,pacman钩子自动产生.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" 会检测机器上的硬件,生成特定于机器的镜像)

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

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

手动生成[编辑 | 编辑源代码]

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

# mkinitcpio -p linux

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

# mkinitcpio -P

可以按照不同的配置文件创建任意数量的内存镜像。想要引导加载的镜像必须在相应的引导加载程序配置中明确写出。

自定义生成[编辑 | 编辑源代码]

可以使用相应的配置文件产生一个镜像。例如,接下来会根据/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

统一内核镜像[编辑 | 编辑源代码]

mkinitcpio 可以生成统一内核镜像(UKIs)。如果安装了 systemd-ukifymkinitcpio 会调用其生成 UKI;如果没有,mkinitcpio 会使用其自有实现。

配置[编辑 | 编辑源代码]

mkinitcpio的主配置文件是/etc/mkinitcpio.conf。也支持插入式(Drop-in)配置文件,如/etc/mkinitcpio.conf.d/mkhooks.conf(当使用 -c 选项和/或使用了含 ALL_config 的预设时无效)。此外,内核软件包的预配置文件位于/etc/mkinitcpio.d(例如:/etc/mkinitcpio.d/linux.preset)。

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

MODULES
在钩子扩展运行前需要加载的内核模块。
BINARIES
内存盘镜像中包含的额外的二进制文件(一般是可执行的命令)。
FILES
内存盘镜像中包含的其他文件。
HOOKS
要执行的钩子扩展,它是在生成镜像时执行的脚本。
COMPRESSION
内存盘镜像的压缩方式。
COMPRESSION_OPTIONS
传递给压缩工具的额外参数,强烈不建议使用,mkinitcpio 可以自动根据压缩算法传递需要的参数(例如对 xz 传递 --check=crc32 to xz), 手动设置了错误的参数可能导致系统无法启动。
MODULES_DECOMPRESS
解压可加载内核模块和固件文件或保持未解压原样。
注意:
  • 一些系统需要的钩子像 lvm2, mdadm_udev, and encrypt 默认 不是开启的 。参见 #钩子(HOOKS) 仔细遵循指示。
  • 存在多个硬盘控制器使用相同的节点名字,但是拥有不同的内核模块(例如,两个SCSI/SATA控制器或2个IDE控制器)应该使用 持久化设备命名persistent block device naming 保证正确的设备被挂载。否则在两次系统启动时根系统的位置可能改变导致内核崩溃。

模块(MODULES)[编辑 | 编辑源代码]

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

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

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

二进制文件和普通文件(BINARIES、FILES)[编辑 | 编辑源代码]

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

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

注意 BINARIESFILESBash数列,配置支持多个选项,用空格隔开。

钩子(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 时被包含进脚本,应该提供如下两个函数:buildhelpbuild 函数描述了需要加入镜像的模块、文件和二进制文件。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单元。

常用钩子[编辑 | 编辑源代码]

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

这篇文章的某些内容需要扩充。

原因: 增加关于hostdata, memdisk, sleepstrip的信息, 找出dmraid等是否在 systemd 为基础的镜像中正常工作或被需要。 (在 Talk:Mkinitcpio#Improvements for the Common hooks table and section about systemd hook 中讨论)
busybox 初始化 systemd 初始化 编译钩子 运行时钩子 (仅busybox 初始化)
base optional 安装初始化目录结构,安装基本工具及其依赖。除非知道你在做什么,总是保持此钩子为第一个钩子,因为当没有使用systemd钩子时,它提供关键的busybox初始化过程。
当使用systemd钩子时此钩子可选,因为它仅提供busybox恢复shell。
注意: 因为root账户在初始化内存镜像是锁定的,恢复shell是不能用的。locked. 参见 archlinux/mkinitcpio/mkinitcpio#205
udev systemd 增加 udevd, udevadm,和一小套udev规则进镜像。 从内核中启动udev守护进程和uevents过程; 创建设备节点。因为不需要用户清晰的明确出必须设备这是简化的引导过程,推荐使用。
usr 增加支持/usr 在独立分区。参见#/usr 放到单独分区 获得更多细节。 在挂载真正根分区后挂载 /usr 分区 。
resume 添加lzolz4内核模块,以允许在使用编译时默认值以外的休眠镜像压缩算法时恢复。添加 systemd-hibernate-resume(8) 二进制文件以支持从通过 HibernateLocation UEFI 变量指定的休眠映像恢复。 试图从"suspend to disk" 状态重新开始。 参见 休眠 做进一步设置。
btrfs 设置必备模块能够让Btrfs 支持Btrfs的多设备分区。需要安装 btrfs-progs 开启功能。Btrfs在单设备时此钩子不需要(filesystems足矣)。 udev 钩子或systemd不存在时,运行 btrfs device scan 组装多设备Btrfs根文件系统。安装btrfs-progs 包使用此钩子。
autodetect 系统扫描后创建设备白名单从而减少内存镜像的尺寸。确定校验进入的模块正确性和完整性。为了自动侦测发挥作用,必须放在其他子系统钩子之前。放在'autodetect'钩子之前的钩子将会被完整安装。
microcode 在未压缩的 initramfs 映像前添加适用于 Intel 和 AMD 处理器的早期微码更新文件。使用/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/中包含探测模块配置文件。
kms KMS 早启动添加 GPU 模块。另外还添加了某些笔记本电脑液晶面板中内置的隐私屏幕所需的模块。
keyboard 为键盘设备增加必要的模块。如果USB或串口键盘在早期用户空间起作用加入此钩子(可以输入密码或和shell交互)。有一个副作用,一些非键盘的输入设备也可能加进来,但这并不可靠。此钩子代替老的 usbinput钩子。
注意: 使用不同的硬件配置启动的系统(例如笔记本电脑连接外置键盘和内置键盘或headless systems)时,此钩子需要放在autodetect之前才能在引导中使用键盘,例如使用encrypt钩子解密加密设备。
keymap sd-vconsole /etc/vconsole.conf加入特定的 键盘映射keymap(s) 到镜像。在早期用户空间如果使用系统加密, 尤其全盘加密, 此钩子放在encrypt钩子之前。 在早期用户空间从 /etc/vconsole.conf 加载指定的键盘映射。
consolefont /etc/vconsole.conf中加入特定的 终端字体 到镜像。 在早期用户空间自/etc/vconsole.conf里,使用特定的终端字体。
block 加载块设备模块。若在 autodetect 挂钩后调用此挂钩,之添加系统中使用的块设备的模块。模块ahcisd_modusb_storageuasmmc_blocknvmevirtio_scsivirtio_blk 会无条件地添加
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 磁盘阵列
encrypt sd-encrypt 增加dm_crypt 内核模块 和 cryptsetup 工具到镜像。 必须安装cryptsetup包。
注意: 启动时反复确认keyboard钩子放在解密设备前面。和/或当使用钥匙文件解锁时,存放钥匙文件的文件系统加入#模块(MODULES) 里。
侦测和解锁加密根系统。参见 #运行时配置

sd-encrypt 参见 dm-crypt/系统配置#使用systemd-cryptsetup-generator英语dm-crypt/System configuration#Using systemd-cryptsetup-generator

lvm2 加入设备映射内核模块和lvm 工具到镜像。 必须安装lvm2 包。 如果根系统在LVM这是必须的钩子。
fsck 增加fsck二进制文件和特定系统帮助文件,允许fsck在挂载前处理根系统(和/usr分区如果有)。如果放在autodetect钩子前仅仅加载的定的帮助文件到根系统。强烈推荐使用此钩子,独立/usr分区需要它。强烈建议如果使用的此钩子同时要加入必要模块保证键盘在早期用户空间使用。
使用这个钩子需要在内核参数加入 rw参数。(讨论). 参见 fsck#启动时检查英语fsck#Boot_time_checking
filesystems 除非在MODULES中加入了文件系统,不然此钩子是必须的。
acpi_override /usr/initcpio/acpi_override//etc/initcpio/acpi_override/ 添加 ACPI 机器语言文件(.aml)到早期未压缩的 initramfs 镜像中,使得内核可以在启动早期重载 ACPI 表(比如 DSDT[1]

编写钩子扩展[编辑 | 编辑源代码]

(*最新的英文文档删除了这部分内容,感觉似乎用些用处暂时留了下来。) 一个 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

提示:lz4 在高压缩率模式(-9)下镜像有2.5的压缩比率,以付出最慢的单线程压缩速度为代价,可以获得最快的解压缩速度。lzo使用轻度较好的压缩模式后仍然有较快的解压速度。 zstd 提供多样解决方案, 通过参数使用多线程压缩方式和大范围压缩水平,参见 zstd(1) § Operation modifiers。 xz在其高压缩预设(-9)中以大约5的缩减因子实现了最小的体积,但代价是解压速度要慢得多。

压缩选项(COMPRESSION_OPTIONS)[编辑 | 编辑源代码]

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

COMPRESSION_OPTIONS='-9'

这个选项可以留空, mkinitcpio 会确保任何支持的压缩方法有必要的标志来产生一个可以工作的镜像。

警告: 使用错误的参数选项可能导致内核不能引导,因为错误参数导致内核不能解压生成的压缩档。

使用默认的 zstd 压缩时,--long选项在节省自定义内核的空间(特别是在使用 EFI 系统分区作为/boot时的双系统设置)非常有效。但是,内存有限的系统可能无法使用此选项解压缩 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 的大小。这会导致在早期启动阶段更高的内存和 CPU 占用,对于内存有限、CPU 性能不足的系统有影响,因为内核将花费更多的时间来解压缩整个 initramfs 映像,而不是加载单个模块和固件时解压缩它们。

提示:在 initramfs 生成过程接近结束时,所有剩余的 .bz2.gz.lz4.lzma.lzo.xz .zst 文件被移动到早期未压缩的 initramfs 映像以避免双重压缩。


运行时配置[编辑 | 编辑源代码]

这篇文章的某些内容需要扩充。

原因: 哪个选项可以在 systemd 钩子工作, 哪个只能在 base-only? (在 Talk:Mkinitcpio 中讨论)

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

从基本钩子启动[编辑 | 编辑源代码]

root=
这是内核命令行中指定的最重要的参数,因为它决定了哪一个设备会被挂载为你的正确的 root 设备。mkinitcpio 可以灵活的允许不同的格式,详见Persistent_block_device_naming#Kernel_parameters
注意: 下面的选项改变了 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,...} 指定一些模块提前加载。 (例如,这可以用来确保多个网络接口的正确顺序。)

参见: 常规故障排除#系统启动问题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=offip=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 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.

使用加密根目录[编辑 | 编辑源代码]

如果使用加密根目录,请参考 Dm-crypt/System configuration#mkinitcpio

/usr 放到单独分区[编辑 | 编辑源代码]

如果将 /usr 放在单独分区,必须满足:

  • 添加 fsck 钩子, /usr/etc/fstab分区表中的passno 参数列为设置为2 以便启动时检查该分区。作为常规推荐 如果想要/usr分区可以在启动是被检查,以上设置是中肯的。没有这个钩子 /usr 永远不能被检查。
  • 如果没使用systemd钩子那么增加usr钩子。这样将会在挂载根系统后挂载/usr 分区。

疑难解答[编辑 | 编辑源代码]

解压缩镜像[编辑 | 编辑源代码]

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

initrd 镜像是一个 SVR4 CPIO 压缩包,通过 findbsdcpio 命令生成,利用可被内核理解的压缩方式被有选择的压缩,参考#压缩方式(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通过安装安装 linux-firmware包获得。其他提供firmware的包可以查看下表或在 official repositoriesAUR 中搜索固件模块名字。

除此以外,警告信息只出现在 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 作为急救模式。

没有发现 PS/2 控制器[编辑 | 编辑源代码]

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

标准急救过程[编辑 | 编辑源代码]

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

在一台机器引导成功,但在另一台引导失败[编辑 | 编辑源代码]

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

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

参考资料[编辑 | 编辑源代码]