initramfs
和 dracut
是 Linux
系统中与系统启动相关的两个概念。在我们进行内核驱动开发以及测试过程中,可能会接触到,网上的博客大都写的比较晦涩难懂,俗话讲:“好记性不如烂笔头”,于是便想自己总结一下,以便后续用到的时候拿出来看一下;经过查阅资料以及实践,下面将进行详细的归纳总结和说明。
1. initramfs 概述
initramfs
是 initial RAM filesystem 的缩写,指的是 Linux
启动时加载的初始文件系统。它是在操作系统启动过程中,由 Linux
内核在非常早期阶段加载的一个小型文件系统,通常包含一个最小化的环境,包括基本的命令行工具和脚本,以便在启动过程中执行必要的操作。
initramfs 的作用
引导过程:
initramfs
是内核加载的第一个文件系统,主要负责挂载根文件系统(/
)并启动用户空间的服务。硬件驱动支持:它通常包含与系统硬件相关的驱动程序和必要的模块(如磁盘、网络等),以确保系统能够访问存储设备并加载根文件系统。
灵活性:与以前的
initrd
(Initial RAM Disk
)不同,initramfs
使用的是压缩的CPIO
文件系统,可以被内核直接解压并加载到内存中,它更加灵活且支持动态构建。【拓展:CPIO】
CPIO
(Copy In/Out
)是一种归档文件格式,它的名称来源于copy in
和copy out
,意味着它可以将文件复制到归档中(归档),以及从归档中复制文件出来。常用于Linux
和Unix
系统中。它主要用于创建和提取归档文件,特别是在生成initramfs
映像时非常常见。详情见CPIO
官方文档(https://www.gnu.org/software/cpio/manual/cpio.html
)。
initramfs 的应用流程
内核加载:内核从 /boot
中加载initramfs
文件。解压缩:内核解压 initramfs
,并将它挂载为一个临时根文件系统。执行启动脚本:在 initramfs
中包含了基本的用户空间工具和脚本,帮助内核探测硬件、加载必要的模块。挂载实际根文件系统: initramfs
负责找到并挂载实际的根文件系统(通常是/dev/sda1
等),然后切换到根文件系统。启动系统:切换后,内核从新的根文件系统启动整个操作系统。
2. dracut 概述
dracut
是一个现代化的、通用的 initramfs
生成工具,能够根据系统的实际需求来构建适当的 initramfs
文件。
dracut 的特点
模块化: dracut
使用模块化设计,构建initramfs
时根据系统的实际情况加载所需的模块,避免加载不必要的驱动和工具,从而提高启动效率。灵活生成:它能够根据具体的系统配置生成不同的 initramfs
文件,比如基于LVM
、加密文件系统(LUKS
)、RAID
等特性。精简高效:生成的 initramfs
只包含启动系统的必要工具和模块,避免了资源浪费。
dracut 的常用命令
dracut -f
:强制重建 initramfs 文件。-f
参数表示覆盖现有的initramfs
文件,通常用于系统内核更新或系统硬件发生变化后,重新生成与新配置匹配的initramfs
。生成的initramfs
映像通常位于/boot
目录下,文件名类似于initramfs-<kernel-version>.img
dracut -v
:显示详细输出,调试生成过程。dracut --list-modules
:列出所有可用的模块。dracut --omit <module>
:在生成initramfs
时忽略指定模块。
dracut 的使用场景
内核更新后:每次系统内核更新时,都会生成新的
initramfs
文件,确保新内核能够正常启动。如果因为某些原因没有自动生成或遇到问题,使用dracut -f
手动重建initramfs
是常见的解决方法。硬件变更:如果添加了新硬件设备或者更改了存储设备配置(如
RAID
、LVM
、文件系统类型等),也需要重新生成initramfs
。修改 initramfs 配置:如果您对
initramfs
的配置进行了修改(如添加了自定义脚本或驱动程序),需要重新生成initramfs
以应用这些更改。修复启动问题:在某些系统启动问题中,比如根文件系统无法挂载、启动过程中找不到设备驱动或者设备驱动无法卸载时,重建
initramfs
可以帮助修复这些问题。设备驱动无法卸载时,使用dracut -f
更新initramfs
的示例如下:[root@localhost ~]# lsmod | grep nfp
nfp 655360 0
[root@localhost ~]#
[root@localhost ~]# rmmod nfp
rmmod: ERROR: could not remove 'nfp': Device or resource busy
rmmod: ERROR: could not remove module nfp: Device or resource busy
[root@localhost src]#
[root@localhost src]# rm -rf /lib/modules/4.18.0-193.28.1.an7.aarch64/kernel/drivers/net/ethernet/netronome/nfp/nfp.ko.xz
[root@localhost src]#
[root@localhost src]# dracut -f #给内核进行重建initramfs文件
/usr/lib/dracut/modules.d/90kernel-modules/module-setup.sh: line 16: /lib/modules/4.18.0-193.28.1.an7.aarch64//kernel/drivers/net/ethernet/netronome/nfp/nfp.ko.xz: No such file or directory
dracut-install: ERROR: installing '/lib/modules/4.18.0-193.28.1.an7.aarch64/kernel/drivers/net/ethernet/netronome/nfp/nfp.ko.xz'
modinfo: ERROR: Module /lib/modules/4.18.0-193.28.1.an7.aarch64/kernel/drivers/net/ethernet/netronome/nfp/nfp.ko.xz not found.
[root@localhost src]# lsmod | grep nfp
nfp 655360 0
[root@localhost src]#
[root@localhost src]# reboot
Remote side unexpectedly closed network connection
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Session stopped
- Press <return> to exit tab
- Press R to restart session
- Press S to save terminal output to file
┌──────────────────────────────────────────────────────────────────────┐
│ • MobaXterm Personal Edition v22.0 • │
│ (SSH client, X server and network tools) │
│ │
│ ➤ SSH session to root@10.8.2.113 │
│ • Direct SSH : ✔ │
│ • SSH compression : ✔ │
│ • SSH-browser : ✔ │
│ • X11-forwarding : ✘ (disabled or not supported by server) │
│ │
│ ➤ For more info, ctrl+click on help or visit our website. │
└──────────────────────────────────────────────────────────────────────┘
Last login: Tue Sep 19 15:46:16 2023 from 10.9.4.195
[root@localhost ~]# lsmod | grep nfp
[root@localhost ~]#
[root@localhost ~]# rpm -qa | grep nfp
[root@localhost ~]#这段代码的主要操作如下:
通过这些操作,我们使用
dracut
重建了initramfs
,在系统重启后成功地移除了nfp
模块。检查并尝试卸载
nfp
模块:发现nfp
模块正在使用中,无法卸载。删除
nfp
模块文件:手动删除了nfp.ko.xz
文件。重建
initramfs
文件:由于nfp.ko.xz
文件已被删除,dracut
报错。重启系统:系统重启后,
nfp
模块不再加载。检查系统中是否还有
nfp
相关的RPM
包:没有找到与nfp
相关的RPM
包。
3. initramfs 和 dracut 之间的关系
dracut
是构建 initramfs
的工具。initramfs
是一个文件系统映像,包含了系统启动时最基本的用户空间工具和驱动,dracut
则是生成这个 initramfs
的软件。dracut
根据系统的实际配置(如磁盘分区、文件系统类型、LVM
、RAID
等)选择合适的模块并生成 initramfs
,从而确保系统在启动过程中可以正常加载硬件驱动并挂载根文件系统。
总结如下:
initramfs
是内核启动时加载的初始文件系统,主要负责挂载系统的根文件系统和启动用户空间。dracut
是生成initramfs
文件的工具,提供灵活的模块化机制,能够根据系统需求生成定制化的启动映像。使用 dracut -f
可以强制重新生成initramfs
,通常用于内核更新或系统硬件配置变更后,确保系统能够正常启动。
4. dracut -f 生成 initramfs 流程图
为了更好地理解 dracut
生成 initramfs
的过程,下面给出一个简化的流程图:
+---------------------+ +-------------------+
| dracut -f 命令 |----> 模块检测 -----> | 选择必要模块 |
+---------------------+ +-------------------+
|
v
+---------------------+ +--------------------+
| 加载硬件相关驱动 |----> 生成 initramfs -----> | 压缩成映像文件 |
+---------------------+ +--------------------+
|
v
+---------------------+ +-------------------+
| /boot 目录中生成 |----> 生成完成 -----> | 准备引导系统 |
+---------------------+ +-------------------+
第一步: dracut -f
命令发起生成initramfs
文件。第二步: dracut
检测系统当前硬件和配置,选择所需的驱动模块。第三步:加载相关模块(如 LVM
、RAID
、磁盘驱动等)并生成initramfs
文件。第四步:将 initramfs
压缩成映像文件并保存到/boot
目录中。第五步:引导过程中,内核从 /boot
加载生成的initramfs
,完成系统启动。
根据以上步骤,dracut
生成的 initramfs
能够保证内核在启动时加载必要的模块和驱动,并顺利挂载根文件系统。
通过理解和正确使用 dracut
和 initramfs
,您可以更好地管理和维护您的 Linux
系统,确保其顺利启动和运行。