1. 内核头文件
内核头文件包含对内核数据结构和API的说明。
* 要使用内核头文件(一般位于/usr/src/linux/x.x.x/include中,包括linux和asm两个重要目录,其中后者是个软链接,配置内核之后才会有)
* 不要使用/usr/include中的头文件(但网上也看到有人使用这些头文件,但试验了一下不行!!)
2. 合法的LKM
合法的LKM目标文件必须含有.modinfo的section,否则运行insmod时会出现"couldn't find the kernel version the modules was compiled for"错误。实现这一点很简单:只要定义MODULE宏、包含头文件<linux/module.h>即可。
3. 版本问题
.modinfo的section中包含版本信息。
使用命令"objdump -- full-content --section=.modinfo mymodule.o"可以查看。
实验过程中遇到的问题:内核2.4.24的debian上编译模块,产生了版本信息为2.6.0-test7的目标文件,后来发现源代码目录中缺 version.h的头文件,而/usr/include/linux中却有个version.h,指使版本号为2.6.0-test7。
4. 编译选项
一般采用"-W -Wall -Wstrict-prototypes -Wmissing-prototypes -O2"。此外注意指定内核头文件的路径,也可以顺便定义MODULE、__KERNEL_两个宏。
5. 关于printk
printk的输出在/var/log/syslog中,如果是纯文字终端,使用"setterm -msg"后可以直接在屏幕上查看输出信息
6. 初始化函数
模块代码中必须至少定义一下两个函数:初始化函数(int init_module(void)),清理函数(void cleanup_module(void))。前者在执行insmod命令时被调用,后者在执行rmmod命令时被调用。
到了2.4,允许为这两个函数自定义名字:<linux/init.h>中给出了两个宏module_init()和module_exit(),可以设定初始化函数和清理函数的函数名。
注意:模块初始化函数不可等同于可执行程序的入口函数,它不是一系列功能指令的起始执行点,只是完成模块的初始化工作,因为模块不提供一次执行,它更类似库。
点击下载原文
LKM备忘录
最新推荐文章于 2024-09-18 08:45:42 发布