lsmod仅显示模块是否加载,不能确认硬件绑定、参数或签名状态;需配合modinfo -p/-n/-f sig_id查看参数、路径和签名,再用lspci/ethtool/dmesg验证实际设备绑定与初始化。

内核驱动就是以模块形式加载的内核代码,lsmod 是查看它们是否已加载的最直接方式;但仅靠 lsmod 无法确认驱动是否真正绑定到硬件,也看不出参数、版本或签名状态——这时候必须配合 modinfo。
lsmod 输出怎么看:Module、Size、Used by 三列的实际含义
lsmod 的输出不是列表,而是依赖关系快照。重点不在“有没有”,而在“谁在用它”和“能不能安全卸载”:
-
Module列是模块名,不等于驱动名(比如nvme是模块,但对应设备可能是nvm0n1) -
Size是内存占用字节数,数值异常小(如12676)可能表示该模块只是封装层,真实逻辑在其他模块里 -
Used by为0不代表模块空闲——它可能正被内核子系统隐式持有(例如nf_conntrack被 netfilter 框架内部引用,不会显示在该列) - 若某模块出现在多行
Used by的依赖链中(如nf_nat同时被xt_nat和nf_nat_masquerade_ipv4引用),说明它是共享基础模块,强行rmmod会导致 panic
modinfo 查什么:不只是作者和描述,关键看 -p、-n、-F sig_id
modinfo 的默认输出信息杂乱,真正影响调试和部署的是这几个参数:
-
modinfo -p <code>模块名:列出所有可调参数,比如modinfo -p igb会显示InterruptThrottleRate: Interrupt Throttling Rate (array of int),这是调优网卡中断的关键入口 -
modinfo -n <code>模块名:返回模块文件路径(如/lib/modules/5.15.0-101-generic/kernel/drivers/net/ethernet/intel/igb/igb.ko),验证模块是否来自当前内核版本,避免版本错配 -
modinfo -F sig_id <code>模块名:检查模块签名 ID,若输出为空且系统启用了CONFIG_MODULE_SIG_FORCE=y,该模块根本无法加载 - 不加参数直接运行
modinfo <code>模块名时,注意srcversion字段——相同源码编译出的模块该值一致,可用于排查“为什么我编译的 ko 加载失败而系统自带的可以”
查驱动是否真在用:lsmod + lspci 或 ethtool 才算闭环
lsmod | grep <code>驱动名 只证明模块加载了,不代表设备正在使用它。常见断点:
- 网卡驱动加载了,但
lspci -k -s <code>PCI地址显示Kernel driver in use: none→ 实际未绑定,可能是vfio-pci抢占了设备 -
ethtool -i <code>接口名显示 driver 字段为空或为unknown→ 驱动没注册 netdev,或设备未完成 probe(此时dmesg | grep -i <code>驱动名常有probe failed) -
lsmod里有uas,但lsusb -t显示对应 USB 设备用的是usb-storage→ 内核根据设备 descriptor 自动降级,uas被忽略
systemd-modules-load.d 配置 vs 实际加载状态不一致怎么办
写进 /etc/modules-load.d/*.conf 的模块不一定真加载成功,原因往往藏在启动日志里:
-
journalctl -b | grep -i "Failed to load module":直接定位失败模块及错误原因(如依赖缺失、签名验证失败) -
systemctl status systemd-modules-load.service:若状态为failed,说明至少一个配置项加载失败,整个服务退出,后续模块全跳过 - 模块名写错(如把
8021q写成802.1q)或路径含空格,systemd-modules-load默认静默跳过,不会报错 - 想验证某个 conf 是否生效,用
systemctl cat systemd-modules-load.service看它实际读取了哪些文件,再比对lsmod输出
模块加载不是“有就行”,要看它是否被设备引用、参数是否生效、签名是否通过——lsmod 是起点,modinfo 是解剖刀,lspci/ethtool/dmesg 才是最终判决依据。











