首先准备开发环境并安装必要工具,然后编写包含初始化和退出函数的内核模块源码,接着创建使用Tab缩进的Makefile进行编译配置,通过make命令编译并用insmod加载模块,最后用dmesg查看输出、rmmod卸载模块;过程中需注意内核版本匹配、GPL声明及避免使用用户空间函数。

编写Linux内核模块程序是深入理解操作系统机制的重要方式。它允许开发者在不重新编译整个内核的前提下,向内核添加新功能。下面通过一个简单的示例,介绍如何开发、编译和加载一个基础的内核模块。
1. 准备开发环境
确保系统已安装必要的开发工具和内核头文件:
- Ubuntu/Debian: sudo apt install build-essential linux-headers-$(uname -r)
- CentOS/RHEL: sudo yum install kernel-devel kernel-headers gcc make
这些组件提供了编译模块所需的Makefile规则和头文件支持。
2. 编写最简单的内核模块
创建一个名为 hello_module.c 的源码文件:
#include#include
#include
static int __init hello_init(void)
{
printk(KERN_INFO "Hello, Kernel Module Loaded!\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_INFO "Goodbye, Kernel Module Unloaded!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple Hello World kernel module");
MODULE_VERSION("1.0");
说明:
- __init 标记初始化函数,模块加载后释放内存
- __exit 标记退出函数,静态链接时不导出
- printk 是内核态打印函数,使用 KERN_INFO 等级别控制日志输出
- 必须包含 GPL 许可证声明,否则加载时会警告
3. 编写 Makefile
在同一目录下创建 Makefile:
obj-m += hello_module.oKDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd)
default: $(MAKE) -C $(KDIR) M=$(PWD) modules
clean: $(MAKE) -C $(KDIR) M=$(PWD) clean
install: sudo insmod hello_module.ko
remove: sudo rmmod hello_module
注意:Makefile 中缩进必须使用 Tab,不能用空格。
4. 编译与测试模块
执行以下命令完成编译和加载:
- make —— 编译生成 hello_module.ko
- make install —— 加载模块
- dmesg | tail —— 查看内核日志输出
- make remove —— 卸载模块
- lsmod | grep hello_module —— 查看是否加载
正常情况下,加载时会在 dmesg 中看到 "Hello, Kernel Module Loaded!",卸载时显示再见信息。
5. 常见问题与调试技巧
内核模块开发容易遇到的问题包括符号未导出、版本不匹配、权限不足等。
- 确保模块编译所用内核头文件与当前运行版本一致(uname -r)
- 使用 modinfo hello_module.ko 查看模块信息
- 若加载失败,查看 dmesg 输出错误原因
- 避免在模块中使用用户空间函数(如 printf、malloc)
基本上就这些。掌握基本框架后,可以逐步尝试添加字符设备、proc 接口或中断处理等功能。不复杂但容易忽略细节。










