Linux内核模块的插入和删除
由于现在编译一次内核需要很长时间,那么有没有一种办法让我们写的代码不需要完全和Linux内核完全捆绑在一起?由此Linux内核提供了一种机制,叫可加载的Linux内核模块(LKD),即在Linux内核运行期间,可以把这个模块加载到Linux内核,当我们不需要这个模块时可以把这个模块卸载。
下面将演示Linux内核模块从插入到删除的全过程:
1、在ubuntu下创建helloworld.c文件,文件内容如下:
1 //必要的头文件
2 #include<linux/init.h>
3 #include<linux/kernel.h>
4 #include<linux/module.h>
5 MODULE_LICENSE("GPL"); //许可证
//模块的初始化函数,在加载的时候调用该函数
6 static int __init lkm_init(void)
7 {
8 printk("Hello World\n");
9 return 0;
10 }
//出口函数,卸载函数时需要调用该函数
11 static void __exit lkm_exit(void)
12 {
13 printk("Goodbye");
14 }
15
16 module_init(lkm_init);//模块入口点
17 module_exit(lkm_exit);//模块出口点
2、在当前目录下创建名为:Makefile(M要大写) 的文件,Makefile文件告诉编译程序的头文件在哪,Makefile文件的内容如下:
还有两点需要特别注意:
**1、**obj-m:=这个赋值语句的含义是说明要使用目标文件module_example.o,建立一个模块,最后生成的模块名为module_example.ko;.o文件是经过编译和汇编,而没有经过链接的中间文件。
2、makefile文件中,若某一行是命令,则它必须以一个Tab键开头,如下面两句前面都是Tab键打出来的,而不是空格
3、开始编译,在当前目录下使用make命令编译,如下:
编译后,使用ls命令查看当前目录,其中helloworld.ko就是我们生成的模块
4、模块插入到正在运行的内核
插入命令:sudo insmod helloworld.ko
这时可能会有疑问,在第1节中我们不是说,加载模块的时候要调用下面函数吗?
static int __init lkm_init(void)
{
printk(“Hello World\n”);
return 0;
}
其实,我们在插入到内核的模块并不会在控制台打印,那么我们可以通过查看日志文件,
使用命令:dmesg
5、把正在运在内核中的模块卸载
命令:sudo rmmod helloworld
同样我们用dmesg查看日志文件,看到卸载模块的出口函数被调用
static void __exit lkm_exit(void)
{
printk(“Goodbye”);
}
7、make clean 清理
清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件