在 Linux 系统中,如果你想查看内核当前到底加载了哪些模块,最直接、也最靠谱的方法就是使用lsmod。它会读取/proc/modules,并输出模块名称、大小(字节)以及Used by(引用计数和依赖模块)等关键信息。不过需要特别注意,Used by显示为0,并不代表该模块一定处于空闲状态;此外,模块名本身不带.ko后缀,而且大小写必须严格区分。实际做筛选时,建议结合awk+grep正则一起处理,这样在查看 Linux 内核模块列表时更准确,也不容易遗漏目标模块。

直接用 lsmod 查看当前已加载的内核模块
lsmod 是最常用的 Linux 查看内核模块命令,能够直接告诉你“当前哪些模块真实加载在内核中”。它读取的是 /proc/modules,并不是磁盘上的模块文件列表,因此输出结果反映的是系统此刻的真实运行状态。
- 执行
lsmod后,通常会看到三列信息:模块名、模块大小(字节数)、Used by(引用计数 + 依赖模块名) Used by列中的数字为 0,并不等于模块没有使用——例如nvidia正在负责图形渲染时,Used by也可能显示为 0,但执行rmmod nvidia依然会失败,并提示Module nvidia is in use- 模块名称不会带
.ko后缀,也不显示完整路径;例如通过insmod ./hello.ko加载后,在lsmod输出里只会显示hello,除非模块代码中额外定义了MODULE_ALIAS
lsmod | grep 过滤模块时总是找不到?要注意模块名变体和大小写
直接执行 lsmod | grep nvme 有时可能无法完整匹配到相关模块,例如 nvme_core 或 nvme_pci,因为很多 Linux 驱动会拆分成多个彼此关联的内核模块。
- 更稳妥的写法是:
lsmod | awk '{print $1}' | grep -E '^(nvme|nvidia|usb|vfio)'—— 先提取第一列模块名,再用正则匹配常见前缀,这样更适合筛选 Linux 模块列表 - 模块名严格区分大小写:
NVIDIA和nvidia完全不是同一个名字,实际加载的模块名通常为小写 - 闭源模块(如
nvidia)如果被标记为 tainted,lsmod默认不会显示T标志,只有查看/proc/modules原始行末尾时才能看到
确认模块是否“可用”而不仅仅是“已加载”,可使用 modprobe -l
lsmod 只能查看已经驻留在内存中的模块,而 modprobe -l 列出的则是磁盘上所有预编译好的 .ko 模块文件路径,更适合判断“系统里是否存在这个内核模块,但当前还没有加载”。
modprobe -l | grep ^/lib/modules/$(uname -r)/kernel/drivers/net/ | head -5可以快速查看网卡驱动模块所在位置- 如果输出路径包含压缩后缀(例如
.ko.xz),说明该模块以压缩形式存储;modprobe加载时会自动解压,而insmod不能直接处理这类压缩模块文件 - 如果执行
modprobe -l | grep xxx没有任何输出,但你明确知道该模块本应存在,那么大概率是depmod -a没有执行过,或者/lib/modules/$(uname -r)目录下根本没有对应模块文件
模块加载失败?别只看 lsmod,还要结合 dmesg | tail 和 modinfo
lsmod 没有显示,并不表示系统从未尝试加载该模块——加载失败的模块根本不会出现在列表中。这种情况下,就需要进一步查看内核日志以及模块元数据。
dmesg | tail -20往往能看到最近一次加载失败的报错信息,例如Unknown symbol in module通常表示依赖缺失,而Operation not permitted往往意味着模块签名校验失败(启用了CONFIG_MODULE_SIG_FORCE)modinfo xxx可以用来确认模块是否存在、路径是否正确、是否包含depends:字段——例如modinfo veth若显示依赖cfg80211,就需要先确认后者已经加载modprobe --showconfig | grep -A5 xxx可以检查该模块是否被blacklist或install指令覆盖,这也是“明明系统里有模块却始终加载不上”的常见原因之一
lsmod 输出中——它可能根本没有被调用,也可能因为加载失败而被内核拒绝,或者被配置规则悄悄拦截。只盯着 lsmod 本身,你看到的永远只是内核模块状态中已经浮出水面的那一部分。