内核启动初期无法挂载根文件系统通常因initramfs缺失、损坏或缺少驱动;需通过手动cpio构建、dracut自动构建、内核内置配置或GRUB参数调试解决。

如果在内核启动初期无法挂载根文件系统,则很可能是 initramfs 缺失、损坏或未正确包含所需驱动与工具。以下是构建与自定义 initramfs 的具体操作路径:
一、理解 initramfs 的作用与加载时机
initramfs 是一个临时的根文件系统,由内核在真正挂载实际根文件系统前加载并执行其中的 init 程序。它必须包含能识别和访问真实根设备所需的内核模块、用户态工具(如 busybox)、设备节点及挂载逻辑。
1、内核通过 CONFIG_INITRAMFS_SOURCE 指定源路径,编译时将其打包进 vmlinuz 镜像内部。
2、若未启用内置 initramfs,需通过 bootloader(如 GRUB)显式传递 initrd= 参数加载外部 cpio 归档。
3、initramfs 解压后,内核会查找并执行 /init 脚本或二进制程序,该程序负责探测存储控制器、加载必要模块、扫描块设备并挂载真实根分区。
二、使用 find 与 cpio 手动构建最小 initramfs
该方法完全绕过构建系统,适用于调试与精简场景,可精确控制每个文件的来源与权限。
1、创建临时工作目录:mkdir -p initramfs/{bin,sbin,etc,proc,sys,dev}。
2、复制静态链接的 busybox:cp $(which busybox) initramfs/bin/,随后进入 initramfs/bin 目录运行 ./busybox --install . 生成所有符号链接。
3、创建基础 init 脚本:echo '#!/bin/sh\nexec /sbin/init' > initramfs/init,并设置可执行权限:chmod +x initramfs/init。
4、生成 cpio 归档:cd initramfs && find . | cpio -o -H newc > ../initramfs.cpio。
三、基于 dracut 工具链自动构建定制 initramfs
dracut 是主流发行版采用的 initramfs 构建框架,支持模块化扩展与硬件自动探测,适合生产环境快速适配新硬件。
1、安装 dracut:在 Fedora/RHEL 系统中执行 dnf install dracut;Debian/Ubuntu 使用 apt install dracut。
2、创建自定义模块目录:mkdir -p /usr/lib/dracut/modules.d/99myroot。
3、在该目录下放置 module-setup.sh 文件,内容包含 install() { inst_hook pre-pivot 99 "$moddir"/myroot.sh },并将 myroot.sh 放入同目录以注入挂载逻辑。
4、触发重建:dracut -f --regenerate-all,生成的镜像默认存放于 /boot/initramfs-$(uname -r).img。
四、修改内核配置启用内置 initramfs 并指定源
当需要将 initramfs 直接嵌入内核镜像(vmlinuz),避免依赖外部 initrd 文件时,必须启用 CONFIG_INITRAMFS_SOURCE 并指向有效目录结构。
1、在内核源码目录执行 make menuconfig,进入 General setup → Initial RAM filesystem and RAM disk (initramfs/initrd) support。
2、启用 Initramfs source file(s) 选项,并在下方输入路径,例如 /path/to/my-initramfs。
3、确保该路径下存在符合 cpio 格式的归档或可被 find/cpio 处理的目录树,且包含可执行的 /init。
4、重新编译内核:make -j$(nproc) && make modules_install && make install,新内核将自带 initramfs。
五、调试 initramfs 启动失败的关键手段
当 initramfs 加载后卡在 “Waiting for root device” 或直接 panic,需借助早期用户空间交互能力定位问题根源。
1、在 GRUB 启动项末尾添加 rd.shell rd.debug 参数,使 initramfs 在失败时自动进入交互 shell。
2、在 shell 中检查关键路径是否存在:ls /dev/sd* /dev/nvme* /sys/block/,确认块设备是否被内核识别。
3、手动加载驱动模块:modprobe ahci; modprobe nvme,再运行 lsmod 验证是否成功。
4、查看设备节点生成状态:udevadm trigger --subsystem-match=block,随后执行 udevadm settle 等待设备就绪。

















