前言
- 本博文的相关操作均是我亲为的来,你萌在跟着做的时候,如果遇到问题可以随时留言,一起探讨。
今天主要写一写Linux内核模块编程,是我的操作系统实验课内容,如果想要看看内核系统调用编程的,看这个
https://blog.csdn.net/babybabyup/article/details/79839734
模块编程
模块编程不同于添加系统调用,不需要重新编译内核,进行起来就十分快捷啦!
模块是一个目标文件,可以完成某种独立的功能,但是自身不是一个独立的进程,不能单独运行,可以动态的载入模块,使其成为内核代码的一部分,与内核其他代码的地位完全相同,当不需要某个模块功能时,还可以卸载模块。
例:打印到日志文件的hello word
编写模块代码
我的工作路径是/helloword
, 用户为root
编写helloword.c
,其内容为
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int helloword_init(void) {
printk(KERN_ALERT"hello word!");//打印hello word
return 0;
}
static void helloword_exit(void)
{
printk(KERN_ALERT "hello world exit\n");//清理时打印hello word exit
}
module_init(helloword_init);//初始化
module_exit(helloword_exit);//清理函数
MODULE_LICENSE("GPL");//许可声明
代码讲解
头文件
module.h
包含了加载模块需要的函数以及符号init.h
初始化以及清理时的定义kernel.h
printk等函数
前两个头文件是每个模块都必须包含的,另外,如果编写带参数的模块,还必须包含moduleparam.h
.
许可声明
MODULE_LICENSE
声明此模块的许可证,我习惯写在最后。如果不进行声明,则会收到内核被污染kernel tainted
警告。- 常见的有意义的声明:
GPL
,GPL v2
,proprietary
等。
初始化与清理
- 初始化主要完成资源申请以及模块注册。返回0表示一切OK,可以进行下一步。
- 清理函数没有返回值。
- 这两个函数必须在
module_init
,module_exit
定义并完成。
编译模块
编写Makefile
在与helloword.c
同一个目录下,编写Makefile
,其内容为:
obj-m :=hello.o
hello-objs:=helloword.o
KDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
- 编译过程是:首先到内核源码目录下读取顶层的Makefile,然后返回模块源码所在目录
- 编译得到的模块名为
hello.ko
obj-m :=hello.o
格式必须是obj-m :=模块名
hello-objs:=helloword.o
格式必须是:模块名-objs:=目标文件
make -C $(KDIR) M=$(PWD) modules
,make -C $(KDIR) M=$(PWD) clean
两句之前为tab
键。
问题总结
遇到了
gcc:command not found
需要安装gcc截图如下
执行命令:yum install gcc
等待完成即可
重新编译时一定要
make clean
不然出现奇奇怪怪得问题。
最后make
成功的截图:
加载模块
执行命令
insmod hello.ko
执行成功不会有任何提示的。
如果要加载带参数的模块则
insmod 模块名 参数=value
dmesg
查看打印消息:
dmesg
已经可以看到
卸载模块
执行命令
rammed hello.ko
再次 dmesg
到这一步就OK啦,操作系统课程实验还有两个模块编程。。。写在这篇博文啦。