前言
很早之前写过内核模块,前两天探究一个问题时又用到了,结果因为忘记了大部分知识又重新学了一遍,这次还是记录一下,以后就不用再查了。
正文
准备工作
内核模块开发与普通应用开发完全不同,再也不是我们熟悉的stdio起手,main开写。而是单独的功能函数。
所以我们要先安装依赖的函数库(内核代码)。
以我的Fedora 29(kenel version 4.18.16-300.fc29.x86_64)为例,自然要安装对应版本的代码库。
sudo dnf install kernel-devel-4.18.16-300.fc29.x86_64
然后在/usr/src/kernel
就可以看到对应代码库了。
开发流程
主要是一个源码文件(以test.c为例)和Makefile文件。
Makefile文件格式相对固定
LINUX_KERNEL_PATH := /usr/src/kernels/$(shell uname -r)
obj-m += test.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
注意目标文件那里必须是obj-m
表示内核模块,obj-y
表示编译到内核,如果写其他的话并不能编译出我们需要的目标文件。
源码文件
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kangkang");
MODULE_DESCRIPTION("hook open sys call module");
static int entry_point(void) {
printk("hello world\n");
return 0;
}
static void exit_point(void) {
printk("bye world\n");
}
module_init(entry_point);
module_exit(exit_point);
当然这个写法也不是唯一的。还可以直接用module_init,而不是传function pointer
。
然后就是编译,安装内核模块,卸载内核模块
$ make
# insmod hello.ko
# rmmod hello
需要注意的是,安装与卸载都要用root权限,并且一个是文件名,一个只是模块名(无后缀)
如果卸载不成功的,简单操作就是直接重启,复杂的。。请自行google。。。
运行结果
通过dmesg
查看
insmod后
rmmod后
最后
来自森酱的友情提示,开发测试内核模块不要用虚拟机,但最好也不要用自己的开发环境。。。你懂的。
康康在腾讯云上测试了一下,发现也无法执行insmod
大概这类操作被禁止了。
然后在内核模块开发遇到的函数,因为没有man
这样方便的手册,只能直接查询源码了,推荐一个不错的查看源码的网站bootlin,可以在各个版本的kernel源码内查询指定的函数,非常方便。