modprobe -d仅静态解析modules.dep.bin中的insmod顺序,不校验文件存在、内核版本或签名;unknown symbol需查/proc/kallsyms,编译期依赖则需nm与module.symvers配合验证。

modprobe -D 只能看静态路径,不能代替真实加载
它输出的是 modules.dep.bin 里预存的 insmod 顺序,比如 modprobe -D vfat 会列两行 insmod 路径,但这些路径不校验文件是否存在、内核版本是否匹配、签名是否通过。常见误判是:看到输出就以为模块“应该能加载”,结果 modprobe vfat 报 FATAL: Module fat not found。
- 先确认
/lib/modules/$(uname -r)/下对应目录和 .ko 文件真实存在,用find /lib/modules/$(uname -r) -name "fat.ko*" - 如果目录缺失或模块名拼错(如写成
fatt),modprobe -D仍可能成功输出——它只查依赖表,不查文件系统 -
$(uname -r)是实际展开值(如6.8.0-45-generic),不是 shell 变量占位符;若该目录不存在,后续所有加载必失败
Unknown symbol 错误必须查 /proc/kallsyms
报 Unknown symbol in module 时,说明运行时符号没注册上,不是路径或文件问题。唯一可信来源是 /proc/kallsyms,它反映当前内核中已导出且可见的符号状态。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 用
sudo cat /proc/kallsyms | grep 'symbol_name'查符号是否出现;非 root 用户看到全是0000000000000000 - 输出形如
ffffffffc1234567 t shared_func [module_a]:第二列t是小写 → 局部符号,其他模块不可见;必须是大写T或D才有效 - 符号在
/proc/kallsyms里没出现?说明导出它的模块根本没加载,先insmod module_a.ko再试 -
EXPORT_SYMBOL_GPL导出的符号,若依赖模块许可证不是 GPL,即使符号存在也会加载失败
编译期依赖要用 nm + Module.symvers 配合验证
开发阶段查跨模块符号引用,不能靠 modprobe 或 dmesg。未加载的 .ko 文件里哪些符号未定义,得用 nm;而“这个符号到底由谁提供”,得看同编译环境生成的 Module.symvers。
- 查模块 B 依赖哪些外部符号:
nm module_b.ko | grep "U ",U表示 undefined - 查某个
U符号由哪个模块提供:grep "symbol_name" /lib/modules/$(uname -r)/build/Module.symvers -
Module.symvers必须和模块编译时一致;若用不同内核头文件或未 clean 编译,该文件内容会失效 - 注意:
Module.symvers不随模块安装进/lib/modules/,它只留在内核构建目录里
depmod -a 不是可选步骤,而是前提条件
modprobe -D、modprobe vfat 等一切依赖解析行为,都基于 modules.dep.bin。这个二进制文件必须由 depmod -a 生成,否则 modprobe 就像瞎子走路。
- 执行
sudo depmod -a后,会更新/lib/modules/$(uname -r)/modules.dep和modules.dep.bin - 常见漏掉场景:升级内核后没重跑
depmod;手动拷贝 .ko 到/lib/modules/后忘了刷新依赖表 - 如果
modprobe -D输出为空或报Module xxx not found,第一反应不是模块损坏,而是depmod -a没跑过 -
depmod -n可预览结果但不写入,适合调试时快速验证依赖关系是否被正确识别
modprobe -D 当成万能诊断工具,却忽略了它不碰文件系统、不查符号表、不验证签名——它只是个路径翻译器。查缺失原因,得按层级切:文件存在性 → 依赖表有效性 → 运行时符号可见性 → 编译期符号归属。每层用的工具和判断依据完全不同。










