模块加载函数必须以“module_init(函数名)”的形式被指定。若初始化成功则返回0,否则返回错误编码。
struct int __init initialization_funcfction(void){
/*初始化代码*/
}
module_init(initialization_function);//指定initialization_function为初始化函数。
2.模块卸载函数(必须)
模块卸载函数必须以“module_exit(函数名)”的形式被指定,无返回值。
struct void __exit cleanup_function(void){
/*释放代码*/
}
module_exit(cleanup_function);//指定cleanup_function为模块卸载函数。
3.模块许可声明(必须)
许可声明描述内核模块的许可权限,如果不声明LICENSE,模块加载时,收到keneltainted警告。
LICENSE包括:GPL,GPLv2,GPL and additional rights, Dual BSD/GPL, Dual MPL/GPL, Proprietary.
声明方法: MODULE_LICENSE(权限);
4.模块参数(可选)
可以用“module_param(参数名,参数类型,参数读/写权限)”为模块定义一个参数。例如:
static char * name;
module_param(name,charp,S_IRUGO);
在insmod时就可以这样传入参数:insmod test.ko name=”zhangsan”
5导出符号(可选)
linux2.6的“/proc/kallsy“文件对应着内核符号表,它记录了符号以及符号所在的内存地址。模块可以使用宏EXPORT_SYMBOL(符号名)或者EXPORT_SYMBOL_GPL(符号名)把符号导出到内核符号表,这样其他模块就可以使用导出的符号表了,使用时用extern声明一下即可。
6.模块声明与描述(可选)
MODULE_AUTHOR(author);//作者
MODULE_DESCRIPTION(description);//模块描述
MODULE_VERSION(version_string);//版本
…
7.一个简单的内核模块例子hello.c。
//hello.c
#include<linux/init.h>
#include<linux/module.h>
static int hello_init(void){/*模块加载函数*/
printk(KERN_INFO "hello world enter\n");
return0;
}
static void hello_exit(void){/*模块卸载函数*/
printk(KERN_INFO "hello world exit\n");
}
module_init(hello_init); /*指定hello_init为模块加载函数*/
module_exit(hello_exit); /*指定hello_exit为模块卸载函数*/
MODULE_AUTHOR("MIAOHY");/*作者*/
MODULE_LICENSE("GPL");/*权限*/
MODULE_DESCRIPTION("Asimple hello world module");/*模块描述*/
MODULE_ALIAS("asimplest module");/*模块别名*/