Linux lsmod 命令(长文解析)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在 Linux 系统的日常运维或开发过程中,了解内核模块的动态加载与卸载机制至关重要。Linux lsmod 呈令作为查看已加载模块的工具,是开发者调试驱动程序、排查系统问题的重要助手。本文将从模块化设计原理出发,结合具体案例,深入解析 lsmod
的核心功能、参数用法及应用场景,帮助读者掌握这一命令的实战技巧。
模块化:Linux 内核的乐高积木
Linux 内核采用模块化(Modular Design)架构,允许用户在运行时动态加载或卸载特定功能的模块。这一设计如同乐高积木:内核是基础框架,而模块则是可自由组合的扩展组件。例如,当需要支持新硬件时,无需重新编译整个内核,只需加载对应的驱动模块即可。
模块的优势体现在三个方面:
- 灵活性:按需加载减少内存占用;
- 可维护性:独立更新模块避免系统重启;
- 兼容性:支持不同硬件的驱动扩展。
通过 lsmod
命令,我们可以直观查看当前系统中已加载的模块列表,进而分析系统资源使用情况或排查模块冲突问题。
lsmod 命令基础用法
命令语法与核心字段
lsmod
的全称为 List Modules,其基本语法如下:
lsmod [选项]
执行 lsmod
命令后,会输出三列信息:
列名 | 含义说明 | 示例值 |
---|---|---|
Module | 模块名称 | kvm_intel |
Size | 模块占用的内存大小(单位:字节) | 235920 |
Used by | 依赖该模块的其他模块或内核子系统 | [nf_nat, ...] |
示例输出解读
Module Size Used by
nf_nat 235920 1
nf_conntrack 143360 1 nf_nat
...(其他模块信息)
nf_nat
是网络地址转换(NAT)模块,占用内存 235,920 字节;Used by
列显示nf_nat
被nf_conntrack
模块依赖,说明nf_nat
的卸载需先卸载nf_conntrack
。
进阶技巧:结合其他工具分析模块关系
1. 筛选特定模块信息
通过 grep
命令可快速定位目标模块。例如,查看与网络相关的 ipv6
模块:
lsmod | grep ipv6
输出可能如下:
ipv6 614400 33 nf_conntrack_ipv6,nf_defrag_ipv6,bridge,...
此结果表明 ipv6
模块被 nf_conntrack_ipv6
等 33 个模块依赖,直接卸载会引发错误。
2. 查看模块详细信息
使用 modinfo
命令可获取模块的元数据,如作者、版本及依赖关系:
modinfo kvm_intel
示例输出片段:
filename: /lib/modules/5.15.0-56-generic/kernel/arch/x86/kvm/kvm-intel.ko
author: Intel Corporation
description: KVM Intel CPU hypervisor
depends: kvm
此处 depends: kvm
表示 kvm_intel
依赖于 kvm
模块,卸载顺序需先卸载子模块。
3. 模块加载与卸载实战
加载新模块
假设系统未加载 usb_storage
模块(用于 USB 存储设备支持),可通过以下步骤:
sudo modprobe usb_storage
lsmod | grep usb_storage
安全卸载模块
卸载前需确保无依赖关系:
lsmod | grep kvm_intel
sudo modprobe -r kvm_intel
模块冲突与问题排查
案例 1:驱动冲突导致设备无法识别
某开发者插入 USB 设备后,dmesg
日志显示:
usb 1-2: device descriptor read/64, error -110
通过 lsmod | grep usb
发现 usbhid
和 usb_storage
同时加载。进一步分析:
modinfo usbhid | grep depends
depends: hid
modinfo usb_storage | grep depends
depends: usbcore
此时需卸载其中一个模块:
sudo modprobe -r usbhid
案例 2:模块内存泄漏诊断
若 lsmod
显示某模块 Size
异常增大,可能是内存泄漏的征兆。例如:
Module Size Used by
my_driver 8192000 0
通过 cat /proc/modules
或 lsmod --all
获取更详细信息,结合 perf
工具定位问题代码。
模块的生命周期管理
加载阶段:动态扩展功能
通过 insmod
或 modprobe
命令可显式加载模块。例如,加载无线网卡驱动:
sudo modprobe iwlwifi
卸载阶段:依赖关系处理
若模块被其他模块依赖,直接卸载会失败:
sudo modprobe -r kvm
Error: Module kvm is in use by: kvm_intel kvm_amd
需先卸载子模块:
sudo modprobe -r kvm_intel && sudo modprobe -r kvm
自动加载机制
Linux 系统通过 udev 和 modprobe.d 配置文件实现模块自动加载。例如,在 /etc/modprobe.d/
中添加:
options kvm ignore_msrs=1
可预设模块参数,避免手动干预。
实战场景:自定义模块开发与调试
步骤 1:编写简单内核模块
创建 hello.c
文件:
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
int init_module(void) {
printk(KERN_INFO "Hello, Linux World!\n");
return 0;
}
void cleanup_module(void) {
printk(KERN_INFO "Goodbye, Linux World!\n");
}
步骤 2:编译与加载模块
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
sudo insmod hello.ko
dmesg | tail
步骤 3:使用 lsmod 验证
lsmod | grep hello
步骤 4:卸载模块
sudo rmmod hello
dmesg | tail
总结
Linux lsmod 命令是理解内核模块机制的核心工具。通过本文的讲解,读者应能掌握以下关键点:
- 模块化设计的原理与优势;
lsmod
输出字段的含义及分析方法;- 结合
modprobe
、modinfo
实现模块管理; - 通过实际案例解决模块冲突与调试问题。
建议读者在真实开发环境中实践上述步骤,逐步深入内核模块的奥秘。掌握这些技能后,您将能更高效地进行驱动开发、系统优化及故障排查,为 Linux 系统的稳定运行提供有力支持。