CentOS实现Linux中的可加载的内核模块
老师ppt上给出一道编程题,要求实现Linux中的可加载的内核模块,且需要至少包含一内核线程。在网络上查询很多资料以后整理归纳了一套适用于CentOS的流程 (其他版本的Linux可能存在命令行不一样,或需要下载某些文件,而CentOS几乎可以直接使用),按照此流程可以顺利将代码插入内核运行并查看,希望能够帮到各位读者。
具体要求
利用如下的系统调用,在Linux系统中实现一个可加载的内核模块,要求里面至少包含一个内核线程。
函数 | 作用 |
---|---|
kthread_run() | 负责内核线程的创建 |
kthread_stop() | 负责结束创建的线程,参数是创建时返回的task_struct指针 |
kthread_should_stop() | 返回should_stop标志;它用于创建的线程检查结束标志,并决定是否退出 |
代码实现
代码结构部分借鉴于网络
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/init.h>
static struct task_struct *test_task;
int thread_fuc(void)
{
int i;
for(i=0; i<1; i++)
{
set_current_state(TASK_UNINTERRUPTIBLE); //设置状态为不可打断
if (kthread_should_stop()) break; //检查结束标志
if (1)
{
printk(KERN_INFO "Hello World!"); //在内核态打印(printf函数是在用户态打印)
}
schedule_timeout(HZ); //让需要延迟的任务睡眠到指定的延迟时间耗尽后再重新运行
}
return 0;
}
static int test_init(void)
{
test_task = kthread_run(thread_fuc, NULL, "test_task");
printk(KERN_INFO"module enter");
return 0;
}
static void test_cleanup(void)
{
if(test_task)
{
kthread_stop(test_task);
test_task = NULL;
printk(KERN_INFO"module remove");
}
}
//以下的module程序不需要main入口
module_init(test_init); //初始化
module_exit(test_cleanup); //退出
将此代码以 .c 形式保存到一个目录下即可
makefile的使用
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,也可以执行操作系统的命令。 —— 百度百科
makefile内容如下:
KVERS = $(shell uname -r)
obj-m := Kernel_test.o
build: kernel_modules
kernel_modules:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
clean:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
注意!!:两条命令 (make -C /lib/modules/KaTeX parse error: Can't use function '$' in math mode at position 17: …KVERS)/build M=$̲(CURDIR) module…(KVERS)/build M=$(CURDIR) clean) 之前一定要加 TAB,否则后期会报错 (*** missing separator. Stop.)。
需要自己改的部分就是 “obj-m :=” 后面的内容,此处用的是 Kernel_test 作为文件名。
将此代码存在 .c 文件的同一目录下,命名为makefile;此时,目录下应该有如下两个文件:
在命令行键入make;此时,目录下的文件如下:
将代码 载入/删除 模块
-
键入 insmod kernel_test.ko 命令将写好的代码载入模块运行 (文件命名不一样的改为 *** .ko);
-
键入 dmesg 命令进行查看 (也可以使用 dmesg | tail -3 查看后三行),运行结果如下:
出现如上情况说明成功。 -
键入 rmmod kernel_test 命令将代码删除 (作用应该是释放空间);
总结
因此,我们总结以下步骤主要为:
在目录下新建 .c 文件编写代码 ——> 在目录下新建 makefile 文件并填入上文代码 ——> 键入make命令 ——> 使用 insmod 载入模块 ——> 使用dmesg查看 ——> rmmod 删除模块