
速成版只学 7 个 PartPart 1内核模块到底是什么 Part 2hello.ko 最小模块 Part 3Makefile 怎么把 .c 编译成 .ko Part 4insmod / rmmod / lsmod / dmesg 生命周期 Part 5字符设备/dev/xxx 是怎么来的 Part 6mmap用户态 Worker 怎么读内核数据 Part 7接回性能监控项目 workflow先不讲Kconfig 静态编译进内核 ARM 交叉编译 模块依赖 EXPORT_SYMBOL 多文件模块Part 1内核模块到底是什么1. 先一句话Linux 内核模块 可以动态插进 Linux 内核里运行的一段代码。它编译后通常是xxx.ko.ko可以理解为Kernel Object也就是给内核加载的目标文件。2. 普通程序 vs 内核模块你平时写的 C/C 程序main() ↓ 运行在用户态 ↓ 通过系统调用访问内核比如printf(hello\n);malloc(1024);open(/proc/stat,O_RDONLY);这些都是用户态程序干的。但内核模块是hello.ko ↓ insmod 加载 ↓ 进入内核地址空间 ↓ 运行在内核态 ↓ 可以直接调用内核 API区别很大对比项普通程序内核模块运行位置用户态内核态入口main()module_init()注册的函数打印printfprintk崩溃影响当前进程崩可能导致系统崩权限低极高加载方式./a.outinsmod xxx.ko所以你先记住内核模块不是一个普通应用程序它是被 Linux 内核加载进去执行的代码。3. 为什么要有内核模块如果没有内核模块你想给内核加功能只能修改 Linux 内核源码 ↓ 重新编译整个内核 ↓ 重启机器太重。有了内核模块之后写 hello.c ↓ 编译成 hello.ko ↓ sudo insmod hello.ko ↓ 模块进入内核 ↓ sudo rmmod hello ↓ 模块卸载所以它解决的问题是不重启、不重新编译整个内核也能临时扩展内核功能。4. 加载模块时发生了什么执行sudoinsmod hello.ko内核大概做这些事1. 读取 hello.ko 文件 2. 检查模块格式和内核版本 3. 把模块代码加载到内核地址空间 4. 解析模块依赖的内核符号 5. 调用 module_init 注册的初始化函数卸载时sudormmod hello内核大概做1. 检查模块是否还被使用 2. 调用 module_exit 注册的退出函数 3. 释放模块占用的资源 4. 从内核模块列表中移除5. 最小内核模块长这样先看不要求你现在全懂#includelinux/module.h#includelinux/kernel.hstaticint__inithello_init(void){printk(hello module init\n);return0;}staticvoid__exithello_exit(void){printk(hello module exit\n);}MODULE_LICENSE(GPL);module_init(hello_init);module_exit(hello_exit);你现在只抓 4 个点代码作用printk内核态打印日志用dmesg看module_init(hello_init)注册模块加载入口module_exit(hello_exit)注册模块卸载入口MODULE_LICENSE(GPL)声明模块许可证注意内核模块没有 main 函数。它靠module_init() module_exit()告诉内核加载和卸载时该调用哪个函数。6. 为什么这和性能监控项目有关你的项目不是为了写 hello 模块而是为了做这个内核模块加载 ↓ 注册字符设备 /dev/xxx ↓ 内核周期性采集 CPU / softirq 累计值 ↓ 把数据写入内核缓冲区 ↓ 用户态 Worker open /dev/xxx ↓ Worker mmap 这块缓冲区 ↓ Worker 读取数据并做差分 ↓ MetricCollector 聚合 ↓ MonitorInfo ↓ gRPC Push 到 Manager所以面试里你不是说我会写 hello world 内核模块。而是说项目里用内核模块把 CPU / softirq 这类高频内核指标暴露给用户态 WorkerWorker 通过字符设备和 mmap 读取减少频繁 read 和数据拷贝开销。这才是项目价值。7. 你现在先背这 6 句1. Linux 内核模块是可以动态加载进内核运行的一段代码通常编译成 .ko 文件。 2. 普通程序运行在用户态内核模块运行在内核态。 3. 内核模块没有 main 函数加载时执行 module_init 注册的函数卸载时执行 module_exit 注册的函数。 4. 内核态不能用 printf要用 printk日志通过 dmesg 查看。 5. 动态加载用 insmod查看用 lsmod卸载用 rmmod。 6. 在性能监控项目里内核模块主要用于采集 CPU / softirq 等高频指标并通过字符设备 mmap 暴露给用户态 Worker。面试版答案面试官问Linux 内核模块是什么你直接答Linux 内核模块是一种运行时扩展内核功能的机制编译后通常是.ko文件。它不是普通用户态程序而是通过insmod加载到内核地址空间执行通过rmmod卸载。模块没有main函数而是通过module_init注册加载入口通过module_exit注册卸载入口。加载时内核会解析模块、完成符号链接然后调用初始化函数卸载时调用退出函数释放资源。在我的性能监控项目里内核模块主要用于采集 CPU 和 softirq 这类高频内核指标并通过字符设备和mmap暴露给用户态 Worker减少频繁系统调用和数据拷贝。