现在的Linux内核十分庞大,驱动繁多,但是仍有一些是内核所不包含的,或者我们前期进行了内核裁剪,但后面又需要添加一些驱动,但是又不想重新烧录内核,这时候就可以使用内核模块功能,对内核驱动进行动态的调整。
下面描述一种最简单的模块编译安装示例,主要参考linux学习笔记(五)编译内核模块生成ko驱动文件_ko文件编译-CSDN博客,但该博客不够完善,特补充说明。
我们先准备一个文件夹,用于测试,比如就叫hello。里面有两个文件hello.c和Makefile。
hello.c的内容如下
#include <linux/init.h>
#include <linux/module.h>
static int __init hello_init(void)
{
printk(KERN_INFO "Hello World enter\n");
return 0;
}
module_init(hello_init);
static void __exit hello_exit(void)
{
printk(KERN_INFO "Hello World exit\n ");
}
module_exit(hello_exit);
MODULE_AUTHOR("mushike");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("A simple Hello World Module");
MODULE_ALIAS("a simplest module");
Makefile 的内容如下
KVERS = $(shell uname -r)
CURDIR= $(shell pwd)
obj-m += hello.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
这个时候其实还有问题,会提示找不到文件,因为我们的hello文件夹位置是自定义的,而头文件是使用的相对路径,所以找不到。
我们需要添加头文件的路径,以VSCODE为例,我们打开hello文件夹。按下“CTRL+SHIFT+P”,然后找到C/C++:Edit configuration(JSON),添加上路径如下所示,我这里使用的是绝对路径,因为是在PC虚拟机上用的,所以架构是X86,如果你是在ARM上开发,记得调整。
接下来使用make就可以编译生成.KO文件了。
使用modinfo查看信息,与我们hello.c中设置的一样。
接下来我们使用insmod进行安装,安装完毕后可以使用lsmod查看 ,可以看到多出了hello模块。
因为我们注册hello时使用printk进行了打印,我们可以查看下内核日志 ,输入dmesg -T,可以看到日志信息,最后一条即为内核模块hello安装时的打印。
以上只是个示例,如果是实际的驱动,比如点亮一个灯这种,那么我们需要将它做成一个字符设备,要做的内容包括跟具体硬件相关的引脚配置,时钟配置,引脚电平操作等。跟linux设备框架相关的需要分配设备名称,内存映射,设备操作函数,创建设备节点等。
全部完成之后通过ls /dev/就可以看到新增的设备,能够对设备进行操作了。