根本原因是驱动未真正进入initramfs或未被正确加载;--add-drivers仅复制模块文件,不保证自动加载,需配合modprobe规则、内核参数(如rd.driver.pre)或dracut配置确保加载。

initramfs 重建后系统卡在 initramfs shell,dracut --force --add-drivers 不生效?
根本原因通常是:驱动没真正进 initramfs,或进了但没被正确加载。常见于新装显卡驱动(如 nvidia)、RAID 卡(如 megaraid_sas)、NVMe SSD 控制器(如 nvme 或厂商定制模块)等场景。--add-drivers 只负责把模块文件复制进去,不保证自动加载——得靠 modprobe 规则或内核命令行触发。
-
--add-drivers参数只接受模块名(不含.ko),且必须是已安装到/lib/modules/$(uname -r)/kernel/drivers/下的模块;若模块依赖其他模块(比如nvidia-uvm依赖nvidia),要一并列出 - 执行前确认当前运行内核和目标重建内核一致:
uname -r和ls /lib/modules/下目录名需匹配,否则dracut会静默跳过驱动复制 - 加
--force是必要的,但仅当已有 initramfs 缓存存在时才强制重生成;若/boot/initramfs-$(uname -r).img不存在,--force实际无作用 - 建议加上
--regenerate-all替代单纯--force,它会清空缓存并重新扫描全部模块,避免旧缓存干扰
如何验证驱动是否真的进了 initramfs
别只信命令返回成功。进 initramfs shell 后执行:lsinitrd /boot/initramfs-$(uname -r).img | grep -E "(nvidia|megaraid|mpt3sas|nvme)" —— 这能直接看到模块文件是否存在。如果没输出,说明 --add-drivers 失败了,常见原因是模块名拼错、路径不对、或模块未编译进内核(lsmod 看不到,modinfo xxx 报错)。
- 模块名必须和
modinfo输出的name:字段完全一致(例如modinfo nvidia | grep name显示name: nvidia,就不能写成nvidia.ko或nvidia_drv) - 某些驱动(如 AMDGPU PRO)带多个子模块,需全部列全:
dracut --force --regenerate-all --add-drivers "amdgpu amdgpu_si amdgpu_cik" - 如果模块位于
/lib/firmware/下的固件(firmware blob),--add-drivers不管它,得用--force-drivers或手动放进/lib/dracut/modules.d/模块里
驱动进了 initramfs,但启动时仍找不到磁盘或设备
这时候问题不在“有没有”,而在“加不加得上”。initramfs 默认只按内核命令行里的 rd.driver.pre、rd.md=0 等规则加载模块;没显式声明的,即使存在也不会自动 modprobe。尤其 RAID、LVM、加密根分区场景下,驱动加载顺序和时机非常关键。
- 在 GRUB 配置中给内核参数追加:
rd.driver.pre=nvme,my_custom_driver rd.modprobe=1(rd.modprobe=1强制启用模块加载机制) - 若驱动需特定参数(如
megaraid_sas的allow_msix=1),不能靠--add-drivers传参,得写进/etc/dracut.conf.d/99-custom.conf:install_items+=" /lib/modules/$(uname -r)/kernel/drivers/scsi/megaraid_sas.ko "+ 配合force_drivers+=" megaraid_sas " - 某些 NVMe 设备在 UEFI 模式下需额外启用
rd.nvme=1,否则即使nvme模块存在,dracut 也不主动 probe
重建后 initramfs 大小异常小(WARNING: kernel version mismatch
这说明 dracut 根本没读对内核树,导致跳过了驱动扫描。典型表现是 --add-drivers 像没执行一样——因为模块列表为空。
- 检查
/lib/modules/$(uname -r)/build是否指向有效的内核源码目录(ls -l /lib/modules/$(uname -r)/build);若为 broken symlink 或空,dracut 会放弃模块分析 - CentOS/RHEL 用户注意:
kernel-devel包版本必须与uname -r完全一致(包括 .el7.x86_64 后缀),否则dracut认为“无可用内核头文件”,不扫描驱动 - Arch Linux 用户:确保已运行
sudo pacman -S linux linux-headers,且linux-headers版本严格匹配当前linux包 - 手动指定内核版本可绕过自动探测:
dracut --force --kver 6.6.30-1-lts --add-drivers nvme
最常被忽略的一点:dracut 不校验模块是否能被 modprobe 正常加载,只管复制文件。所以即便 lsinitrd 看到模块在,也得进 initramfs shell 手动 modprobe xxx 测试是否报 Invalid argument 或 Unknown symbol——那说明模块依赖缺失或 ABI 不兼容。










