1. Linux内核模块基础概念
在Linux系统开发中,内核模块(Loadable Kernel Module,LKM)是一种可以在运行时动态加载到内核中的代码块。与直接编译进内核的代码不同,模块提供了极大的灵活性,允许我们在不重新编译整个内核的情况下扩展系统功能。
我第一次接触内核模块是在为一个嵌入式设备开发定制驱动时。当时需要为一块特殊的传感器编写驱动程序,但又不想重新烧写整个系统镜像。内核模块完美解决了这个问题——只需要编译生成.ko文件,通过insmod加载就能立即使用。
内核模块最常见的应用场景包括:
- 设备驱动程序开发
- 文件系统实现
- 网络协议栈扩展
- 系统监控和安全模块
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 模块声明的基本结构
2.1 模块宏定义
每个Linux内核模块都必须包含两个最基本的宏定义:
c复制#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_LICENSE()指定模块的许可证,这是强制要求的。常见选项包括:
- "GPL":GNU通用公共许可证
- "GPL v2":GPL第二版
- "Dual BSD/GPL":双重许可
- "Proprietary":专有许可(但可能不被内核接受)
注意:如果未指定许可证或使用非GPL兼容许可证,模块可能会被标记为"tainted",某些内核功能将不可用。
2.2 模块描述信息
除了基本的许可证和作者信息,我们还可以添加更多描述性信息:
c复制MODULE_DESCRIPTION("A simple example Linux module");
MODULE_VERSION("1.0");
MODULE_ALIAS("example-module");
这些信息可以通过modinfo命令查看,对于模块的维护和使用非常有帮助。在实际项目中,我习惯为每个模块都添加详细的描述信息,这在团队协作时能大大减少沟通成本。
3. 模块的初始化和退出函数
3.1 初始化函数
每个模块都需要一个初始化函数,在模块加载时被调用:
c复制static int _
