mkinitcpio
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.
值得注意的是,initial ramdisk 阶段的各种任务有两种不同的执行方式:
- 基于 Busybox 的初始化内存镜像
- 启动一个 init 脚本,该脚本依次扫描 initial ramdisk 的文件系统以查找要执行的脚本(在此上下文中称为运行时挂钩)。
- 基于 systemd 的初始化内存镜像
- systemd 已在 initial ramdisk 阶段开始时启动。要执行的任务由常规的 systemd 单元文件确定。请参阅 systemd bootup process
选择哪种方式由 /etc/mkinitcpio.conf
的 HOOKS
数组中是否存在 systemd
钩子决定的。更多细节请参阅 #常用钩子
安装[编辑 | 编辑源代码]
安装软件包 mkinitcpio包。这个软件包是 linux包 软件包的依赖,应该已经自动安装了。高级用户可以从mkinitcpio-gitAUR 获取 mkinitcpio 的最新开发版本.
创建和启用镜像[编辑 | 编辑源代码]
自动匹配生成[编辑 | 编辑源代码]
每次安装或升级内核,pacman钩子自动产生.preset文件,保存在/etc/mkinitcpio.d/
。例如:linux.preset
文件是官方稳定版linux包包产生的。一个preset是简明的创建初始化内存镜像需要的列表信息,以取代手动明确各种参数和输出文件位置。默认mkinitcpio都会创建两个内存盘镜像:
- 默认镜像
/boot/initramfs-linux.img
按照mkinitcpio #配置明确的指令生成。 - fallback镜像
/boot/initramfs-linux-fallback.img
。产生过程和上面一样。唯一区别,就是创建时跳过了autodetect钩子扩展,因而它包含全范围内更多的内核模块,可以支持大部分系统。(ps: "autodetect" 会检测机器上的硬件,生成特定于机器的镜像)
生成preset之后,pacman钩子会利用preset提供的信息调用 mkinitcpio 脚本创建上面的两个镜像。
手动生成[编辑 | 编辑源代码]
手动运行脚本,参照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-ukify包,mkinitcpio 会调用其生成 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
数组中。 - 当使用 encrypt 或 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
和 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 初始化 | 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 | 添加lzo 和lz4 内核模块,以允许在使用编译时默认值以外的休眠镜像压缩算法时恢复。添加 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 挂钩后调用此挂钩,之添加系统中使用的块设备的模块。模块ahci 、sd_mod 、usb_storage 、uas 、mmc_block 、nvme 、virtio_scsi 和virtio_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。 |
lvm2 | 加入设备映射内核模块和lvm 工具到镜像。 必须安装lvm2包 包。 如果根系统在LVM这是必须的钩子。 |
– | |
fsck | 增加fsck二进制文件和特定系统帮助文件,允许fsck在挂载前处理根系统(和/usr分区如果有)。如果放在autodetect钩子前仅仅加载的定的帮助文件到根系统。强烈推荐使用此钩子,独立/usr 分区需要它。强烈建议如果使用的此钩子同时要加入必要模块保证键盘在早期用户空间使用。 使用这个钩子需要在内核参数加入 rw 参数。(讨论). 参见 fsck#启动时检查。 |
– | |
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
。
-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 映像,而不是加载单个模块和固件时解压缩它们。
运行时配置[编辑 | 编辑源代码]
。
运行时配置选项可以通过内核命令行传递到 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 磁盘阵列[编辑 | 编辑源代码]
使用 net[编辑 | 编辑源代码]
必须的包
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。
<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 压缩包,通过 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
激活/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 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 镜像的生成:
- 在所有位于
/etc/mkinitcpio.d/
中的 .preset 文件中修改PRESETS=('default' 'fallback')
行,为PRESETS=('default')
。 - 移除fallback镜像:
# rm /boot/*-fallback.img
。 - 重新生成引导记录 (例如,对于 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
信息,加 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