编译加载内核模块
首先先创建一个文件夹hello
mkdir hello
cd hello
vi hello.c
编写一个hello.c文件内容如下:
#include <linux/module.h>
// module.h 定义了内核模块相关的函数、变量及宏。
#include <linux/kernel.h>
// kernel.h 定义了经常用到的函数原型及宏定义。
#include <linux/init.h>
// init.h 定义了驱动的初始化和退出相关的函数。
MODULE_LICENSE("GPL");
// "GPL" 是指明了 这是GNU General Public License的任意版
static int hello_init(void)
{
printk(KERN_ALERT "HELLO OS KERNEL\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "GOODBYE OS KERNEL\n");
}
module_init(hello_init);
module_exit(hello_exit);
然后编写Makefile
vi Makefile
内容如下
obj-m :=hello.o
# 指定模块名hello.ko
KERNEL_DIR :=/lib/modules/$(shell uname -r)/build
# 内核模块的路径,uname -r来获取当前使用的内核
PWD :=$(shell pwd)
# pwd得到当前文件夹路径
all:
make -C $(KERNEL_DIR) M=$(PWD) modiles
# 编译指令
clean:
make -C $(KERNEL_DIR) M=$(PWD) clean
# 清除指令
然后执行
make
可以看到生成了hello.ko文件
查看模块信息
modinfo hello.ko
将模块动态加载到内核
insmod hello.ko
可以通过
lsmod查看模块信息
可以看到hello模块已经载入成功了。
最后执行
dmesg
来查看内核日志的输出,在日志的最后一行就有hello os kernel
到这里动态加载内核模块就成功了,随后可以执行
rmmod hello
来删除模块。
总结
当把需要的功能编译到内核中时,内核会变得越来越庞大,对功能进行修改又需要重新编译内核,这对于一些只在特定场合才会使用的功能来说就很不方便,因此Linux提供了一种机制--模块(module)。模块本身不会被编译到内核中,从而控制了内核的大小,当需要时就可以被动态的加载到内核中去。一旦模块被加载到内核中,那么它就和内核中的其他部分完全一样了。
内核比作weindows系统,那么模块就是系统中的应用程序,可以动态的增删。
lsmod
命令可以查看当前内核中的模块。而rmmod
命令可以删除模块,insmod
命令可以加载模块。
加载模块的第一步就是编译模块,而如果是现有的模块的话,也有命令可以直接加载。
Makefile是mkae
编译命令所需要的文件,make命令会根据这个文件进行编译。我们分析上面的Makefile的文件可以知道,实际上编译就是执行了下面这条命令。
make -C $(KERNEL_DIR) M=$(PWD) modules
-C是表示进入$(KERNEL_DIR)目录执行makefile,而M不是makefile的选项,是内核根目录下的Makefile中使用的变量。KERNEL_DIR实际上就是内核的模块的路径,我们需要把模块编译到这个地方,加载现有的模块也是在这里加载的。
结语
本次的文章到这里就结束啦!♥♥♥读者大大们认为写的不错的话点个赞再走哦 ♥♥♥
每天一个知识点,每天都在进步!♥♥