Hello Module
Linux设备驱动属于内核的一部分,Linux内核的一个模块可以以两种方式被编译和加载:
(1)直接编译进Linux内核,随同Linux启动时加载;
(2)编译成一个可加载和删除的模块,使用insmod加载(modprobe和insmod命令类似,但依赖于相关的配置文件),rmmod删除。这种方式控制了内核的大小,而模块一旦被插入内核,它就和内核其他部分一样。
下面我们给出一个内核模块的例子:
#include <linux/module.h> //所有模块都需要的头文件 |
分析上述程序,发现一个Linux内核模块需包含模块初始化和模块卸载函数,前者在insmod的时候运行,后者在rmmod的时候运行。初始化与卸载函数必须在宏module_init和module_exit使用前定义,否则会出现编译错误。
程序中的MODULE_LICENSE("GPL")用于声明模块的许可证。
如果要把上述程序编译为一个运行时加载和删除的模块,则编译命令为:
gcc -D__KERNEL__ -DMODULE -DLINUX -I /usr/local/src/linux2.4/include -c -o hello.o hello.c |
由此可见,Linux内核模块的编译需要给gcc指示-D__KERNEL__-DMODULE -DLINUX参数。-I选项跟着Linux内核源代码中Include目录的路径。
下列命令将可加载hello模块:
insmod ./hello.o |
下列命令完成相反过程:
rmmod hello |
如果要将其直接编译入Linux内核,则需要将源代码文件拷贝入Linux内核源代码的相应路径里,并修改Makefile。
Issue1: gcc版本和linux内核版本不一致
./hello.o: kernel-module version mismatch ./hello.o was compiled for kernel version 2.4.9-9 while this kernel is version 2.4.18-14. |
这说明内核和编译器版本号不匹配,修改让两者相同即可
非常感谢liujunberg朋友的解答,我修改了编译器的版本号使之适应于内核版本号,问题解决了!
另外的版本不一致的解决方法是:http://www.linuxsir.org/bbs/thread209644.html (标题: 请教一个非常简单的模块程序加载的问题,请大家帮帮忙。) |
Issue2:查看printk输出的信息
dmesg |
Issue3:如何查看增加删除模块的效果
Cat /proc/modules |