第四章 Linux内核模块
4.1 概念与结构
--模块本身不被编入内核镜像,控制内核大小
--模块一旦加载,就会成为内核一部分
--modprobe比insmod强大,会同时加载模块依赖
--模块间依赖关系在/lib/modules/<kernel-version>/modules.dep,由depmod工具生成
******************依赖生成文件关系图********************
--modinfo可查看模块信息
**********************modinfo生成的模块信息图.jpg*************************************
--
4.2 内核模块程序结构
1.模块加载函数
static int __init initialization_func(void){
}
module_init(initialization_func);
--内核中可以采专用reques_moduel(module_name)方式加载内核模块
--所有__init编译进内核都会成为镜像一部分,连接时都会放在.init.text区段内部。
#define __init __attribute__((__section__(".init.text")))
--数据可定义为__initdata,__exitdata。用于初始化阶段需要的数据,内核在初始化完,也可以释放他们占用的内存。
static int hello_data __initdata = 1;
2.模块卸载函数
static int __exit exit_func(void){
}
module_exit(exit_func);
3.模块许可证声明 GPL、GPLv2 GPL and additional rights DUSL BSD/GPL等等 MODUEL_LICENSE("GPL v2")
4.模块参数
module_param(参数名,参数类型,参数读写权限)为模块定义一个参数,
********************带参数的内核模块******************
查看/var/log/messages可以看到输出
5.模块导出符号
--/proc/kallsyms --对应着内核符号表,记录符号以及符号所在的内存地址。
EXPORT_SYMBOL(符号名);
EXPORT_SYMBOL_GPL(符号名);
--导出符号可被其他模块使用,只需要声明一下即可
*********************内核模块中的符号导出************
6.模块作者信息声明
7. MODULE_XX()支持系列内容
8.USB,PCI等设备驱动用MODULE_DEVICE_TABLE表明支持的设备.如下
//table of devices that work with this driver
static struct usb_device_id skel_table {} ={
( USB_DEVICE(USB_SKEL_VENDOR_ID,
USB_SKEL_PRODUCT_ID))
() //terminating enttry
};
MODULE_DEVICE_TABLE(usb,skel_table);
4.3-7 模块加载函数.
4.8 try_module_get(&module)和module_put(&module)管理计数,并且考虑了SMP和PREEMPT机制的影响。
4.9 独立的linux内核模块的Makefile文件编写方法和模块编译方法
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
mkae -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
多个文件时候
obj-m ;= modulename.o
modulename-objs := file1.o file2.o
4.10 绕开GPL的问题