Linux编程之内核模块编程.pdf
H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up pLinux编程之2 内核模块编程(LKM)H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up p什么是LKMLKM:就是可加载的内核模块(LoadableKernel Module)。这中模块本来是Linux系统用于扩展他的功能的。使用LKM的优点有:他们可以被动态的加载,而且不需要重新编译内核。由于这些优点,他们常常被特殊的设备(或者文件系统),例如声卡,网卡,romfs等使用。H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up pLKM 的基本结构int hello_init(void)/*用于初始化所有的数据,函数名可以自定义*/void hello_exit(void)/*用于清除数据从而能有一个安全的退出,函数名可自定义*/module_init(hello_init);/*加载模块*/module_exit(hello_exit);/*卸载模块*/H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up pLKM的头文件(include)头文件的位置:/usr/src/linux-2.6.x/include/一个模块所必需的头文件:#include#include 其它头文件H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up p最简单的LKM/*hello.c*/#include#include static int hello_init(void)/*用于初始化*/printk(KERN_ALERT Hello,worldn);return 0;static void hello_exit(void)/*用于清除从而能安全退出*/printk(KERN_ALERTGoodbye worldn);MODULE_LICENSE(GPL);module_init(hello_init);/*加载模块*/module_exit(hello_exit);/*卸载模块*/H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up pLKM的编译准备编译的准备工作:1.与此时运行的内核版本一致的内核源代码一套将其解压放置到/usr/src/目录下,下载网站:http:/www.kernel.org/pub/linux/kernel/v2.6/2.make工具make在执行时,需要一个命名为Makefile的文件。这个文件告诉make以何种方式编译源代码和链接程序。(2.6下内核模块编译必须是Makefile)H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up pLKM的Makefile文件与编译Makefile文件的位置:与编写的LKMc文件放在同一个目录中。编写:obj-m:=hello.okernel_path=/home/xux/linux-2.6all:make-C$(kernel_path)M=$(PWD)modulesclean:make-C$(kernel_path)M=$(PWD)clean编译:makeH He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up pLKM的使用工具http:/www.kernel.org/pub/linux/utils/kernel/module-init-tools/insmod hello.koModinfo hello.kormmod hellomodprobeH He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up p内核模块中的宏(1)#define _init_section(.init.text)_cold notrace#define _exit_section(.exit.text)_exitused _coldcompiler.h:#define _section(S)_attribute_(_section_(#S)H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up p内核模块中的宏(2)MODULE_LICENSE(_license)MODULE_AUTHOR(_author)MODULE_DESCRIPTION(_description)MODULE_VERSION(_version)H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up p内核模块中的宏(3)module_param(name,type,perm)Name:变量名Type:byte,short,ushort,int,uint,long,ulong,charp,bool or invbool,perm:变量权限H He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up p多个模块的编译C文件:hello.c,hello2.c,hello3.c.obj-m:=hello.oobj-m:=hello2.oobj-m:=hello3.okernel_path=/home/xux/linux-2.6all:make-C$(kernel_path)M=$(PWD)modulesclean:make-C$(kernel_path)M=$(PWD)cleanH He el li ig gh ht t.X Xu u X Xi iy yo ou u L Li in nu ux xG Gr ro ou up p多个C文件编译一个模块C文件:hello1.c hello2.c目标模块:hello.koobj-m:=hello.ohello-y:=hello1.o hello2.okernel_path=/home/xux/linux-2.6all:make-C$(kernel_path)M=$(PWD)modulesclean:make-C$(kernel_path)M=$(PWD)clean