modprobe -d 是唯一能直接输出完整模块加载顺序的命令,但它仅静态解析 modules.dep.bin、不校验文件存在性、签名或 secure boot 状态,故结果仅为理论链而非实际运行依赖。

直接用 modprobe -D 查,这是唯一能输出完整加载顺序的命令;但别只信它——它不校验文件是否存在、不检查签名、也不管 Secure Boot 是否拦路。
为什么 modprobe -D 是首选,但它会“骗人”
它读的是 /lib/modules/$(uname -r)/modules.dep.bin,纯静态解析,只拼路径、不验证实际环境:
- 即使
vfat.ko文件根本不存在,modprobe -D vfat仍可能输出两行insmod路径 - 输出里的
$(uname -r)是真实展开值(比如6.8.0-45-generic),不是占位符;若对应目录缺失,后续加载必失败 - 它反映的是“理论加载链”,不是运行时符号依赖——比如
fat.ko缺少导出符号,-D完全不报错
查不到依赖?先确认 depmod -a 是否跑过
modprobe -D 输出为空或报 Module xxx not found,基本等于 modules.dep.bin 没生成或已过期:
- 手动触发重建:
sudo depmod -a(推荐,自动适配当前内核) - 升级内核后用了旧版
depmod?应指定版本:sudo depmod -a 6.8.0-45-generic -
depmod -n只模拟输出,不写入磁盘——不能代替-a - 手动拷贝新模块到
/lib/modules/$(uname -r)/后,必须再跑一次depmod -a
加载失败时,modprobe -D 不够用,得看三处
报 FATAL: Module xxx not found 或 Operation not permitted,光看 -D 解决不了问题:
-
find /lib/modules/$(uname -r) -name "xxx.ko*"—— 确认文件真存在 -
dmesg | tail -20—— 加载瞬间的内核日志,常含Unknown symbol或signature verification failed -
cat /proc/kallsyms | grep -w "symbol_name" | grep "\[module_name\]"—— 验证符号是否已导出且可见(需 root;小写t/d是局部符号,其他模块不可见)
编译期依赖怎么查?nm 和 Module.symvers 才是关键
开发阶段定位跨模块调用失败,不能靠运行时工具:
-
nm module_b.ko | grep "U "—— 列出所有未定义符号(U表示依赖外部) -
grep "shared_func" /lib/modules/$(uname -r)/build/Module.symvers—— 查该符号由哪个模块导出、许可证类型(EXPORT_SYMBOL_GPL会导致非 GPL 模块加载失败) - 注意:模块没加载时,
/proc/kallsyms里不会出现它的符号——insmod后再查才有效
真正卡住的地方往往不在依赖链本身,而在符号导出权限、Secure Boot 签名、或 modules.dep.bin 没随新模块更新——这些点不手动验证,modprobe -D 再快也没用。











