前言
本系列文章适合有c语言基础,并想要接触linux内核的同学。最好能有一定的linux使用基础。
首先在用户目录下创建文件夹hello,该文件夹中包含三个文件:hello.c、build、Makefile下面看详细内容。
hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void){
printk(KERN_ALERT "Hello , world\n");
return 0;
}
static void hello_exit(void){
printk(KERN_ALERT "Goodbye , cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
让我们从前向后看:首先我们引入了两个头文件,这两个头文件的内容在此不作深究,几乎所有的动态加载模块都需要这两个头文件。
宏(MODULE_LICENSE)是用来告知内核,该模块带有一个自由的许可证;没有这样的说明,在模块加载时内核有出错信息。关于出错信息可以在linux日志/var/log/kern.log中查看。
接下来是两个函数:里面只有一个打印语句,与常见的printf不同的是,我们这里使用了printk。printk函数在Linux内核中定义并且对模块可用;它与标准C库函数printf的行为相似。
内核需要它自己的打印函数,因为它靠自己运行,没有C库的帮助。模块能够调用printk是因为,该模块连接到内核可存取内核的公用符号(函数和变量).KERN_ALERT是消息的优先级,该宏定义在printk.c中。
moudle_init和module_exit这两行使用了内核宏来指出这两个函数的角色,当模块加载时执行hello_init函数,当模块卸载时执行hello_exit函数。
Makefile
obj-m := hello.o
在软件开发中,make是一个工具程序(Utility software),经由读取叫做“Makefile”的文件,自动化建构软件。在这里我们不必深究它是如何工作的,这个工具非常重要,在后面会有详细的介绍。
build
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
编译模块
打开命令行,执行以下命令:
cd hello
sh build
这时可以看到,在同级目录下生成模块hello.ko。
模块的装载、查看、卸载
sudo insmod hello.ko //装载模块hello.ko
lsmod | grep hello//查看hello模块是否存在
sudo rmmod hello.ko//卸载hello模块
查看日志文件
sudo tail -n 5 /var/log/kern.log
或者用gedit打开/var/log/kern.log
sudo gedit /var/log/kern.log
能够看到
Hello , world
Goodbye , cruel world
证明模块正常安装、卸载。
有兴趣的同学可以多了解一些printk的相关资料,尝试不同的打印方式。