内核模块的编写有一定的格式要求,这样模块才能被内核识别,即加载成功。如例所示,为一个简单的内核模块程序。
```c
```c
1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/kernel.h>
4
5 int init_module(void){
6 printk(KERN_INFO "module init\n");
7 return 0;
8 }
9
10 void cleanup_module(void){
11 printk(KERN_INFO "module cleanup\n");
12 }
13
14 MODULE_LICENSE("GPL");
如例所示,内核模块与应用一致,都需要声明头文件,不同的是这里的头文件出自于Linux内核。例如,头文件<linux/init.h>指的是内核源码中的include/linux/init.h,需要注意的是内核代码中使用头文件都需要指定头文件所在的上一层目录名。例4-1中,<linux/init.h>头文件包含了init_module与cleanup_module两个函数原型声明;<linux/kernel.h>头文件包含了printk函数的原型声明。
如例中,第5~8行代码为模块的加载(初始化)函数,当模块被动态加载到内核时,内核将自动执行该函数,初始化函数返回值为int类型,默认返回0表示执行成功;第10~12行代码为模块的卸载函数,当模块被卸载时,内核将自动执行该函数;第6行与第11行代码为内核代码中调试打印的函数printk,类似于应用程序中的printf,不同的是prink函数具有打印级别,当输出的级别小于终端的级别时,打印信息是无法显示的。