Linux为每个模块都预留了相应的地址,注册模块即让该模块对内核可见,这也是模块工作的先决条件。注册之后,我们就可以通过查看内核输出信息dmesg命令来查看模块的运行情况。经常使用内核函数printk()来输出系统信息进行打印调试。使用insmod XXX.ko加载一个模块,使用rmmod XXX.ko卸载一个模块,使用lsmod查看当前系统中的模块及其引用情况
insmod使用的是init_module()系统调用,这个系统调用的实现是sys_init_module()
rmmod使用delete_module()系统调用,这个系统调用的实现是sys_delete_module()
注意这里的授权是必须的,如果一个模块没有授权,那么很多需要该授权的函数甚至都不能使用,同理,不合适的授权也会导致模块运行或加载的错误,所以初学者一定不要忽视这个授权,相关授权的选项在"linux/module.h"中,这里我把相关的说明贴出来供大家参考
/* * The following license idents are currently accepted as indicating free * software modules * * "GPL" [GNU Public License v2 or later] * "GPL v2" [GNU Public License v2] * "GPL and additional rights" [GNU Public License v2 rights and more] * "Dual BSD/GPL" [GNU Public License v2 * or BSD license choice] * "Dual MIT/GPL" [GNU Public License v2 * or MIT license choice] * "Dual MPL/GPL" [GNU Public License v2 * or Mozilla license choice] * * The following other idents are available * * "Proprietary" [Non free products] */另一个细节是Linux内核源码的默认头文件路径是顶层目录的include目录,所以包含头文件的时候include可以省略,
第一个Linux模块 #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> static int __init demo_init(void) { printk(KERN_INFO"demo_init:%s,%s,%d"__FILE__,__func__,__LINE__); return 0; } static void __exit demo_exit(void) { printk(KERN_INFO"demo_exit:%s,%s,%d"__FILE__,__func__,__LINE__); } module_init(demo_init); module_exit(demo_exit); MODULE_LICENSE("GPL");执行insmod xjDemo.ko,查看执行结果
我们编写的模块还可以在insmod的时候传入参数,Linux提供了几个宏(函数)用于接收外部的参数。模块内部使用这些函数,只需执行insmod xjDemo.ko num=2等命令就可以将参数传入模块
module_param(num,type,perm); //接收一个传入的int数据 module_param(num,type,perm); //接收一个传入的charp数据 module_param_array(num,type,nump,perm); //接收一个数组 module_param_string(name,string,len,perm); //接收一个字符串