你有没有好奇过,Linux内核里那些神奇的驱动到底是怎么写的?其实不用怕复杂,今天我们就用不到30行代码,写一个能跑起来的最小内核模块,带你感受一下内核编程的快乐。
一、先搞懂:内核模块是什么?
简单说,内核模块就是可以动态加载/卸载到Linux内核里的代码片段,不需要重启整个系统,就能给内核“打补丁”或者加新功能。
我们今天写的这个模块,功能超级简单:
•加载时:打印一句「Hello, kernel module loaded!」
•卸载时:打印一句「Hello, kernel module unloaded!」
二、代码实现:两行核心逻辑
1. 模块源码 hello.c
关键知识点:
•__init:标记函数只在加载时执行,之后内核会回收这段内存
•__exit:标记函数只在卸载时执行
•printk:内核里的「printf」,日志会存在内核缓冲区里
•module_init/module_exit:告诉内核“这是我的入口/出口函数”
2. 编译脚本 Makefile
作用:
•obj-m:告诉内核编译系统,我们要把 hello.o 编译成可加载模块(.ko)
•KDIR:指向当前系统内核的源码/头文件目录
•make modules:调用内核的构建系统,帮我们完成编译
三、编译 & 运行:一步一步来
1. 编译模块
在代码目录下执行:
你会看到类似这样的输出,最后生成 hello.ko 文件:

提示:如果提示缺少内核头文件,先装一下:sudo apt install linux-headers-$(uname -r)
2. 加载模块
Bash sudo insmod hello.ko |
加载后,用 dmesg 查看内核日志,就能看到我们的打印信息:

也可以用 lsmod 确认模块是否加载:
3. 卸载模块
再看日志,就能看到卸载时的打印:
四、常见问题小提示
1.编译报错:缺少vmlinux
像图里的 Skipping BTF generation... 只是警告,不影响 .ko 文件使用,不用管它。
2.权限不够
加载/卸载模块必须用 sudo,因为这是内核级操作。
3.看不到printk日志
用 dmesg 或 journalctl -k 查看内核日志,别用 printf 那套。
五、总结
你看,Linux内核驱动并没有想象中那么可怕。这个最小的例子,已经包含了内核模块最核心的骨架:
•入口/出口函数
•模块注册
•内核日志打印
接下来你可以试着:
•给模块加参数
•操作硬件寄存器
•写一个真正的字符设备驱动
参考代码,关注LinuxROS公众号回复helloDriver