Linux编译第一个驱动HelloDriver!
硬件平台信息:
蓝莓派4B+ubuntu22.04-raspi
哪些是linux驱动
当你编撰一个Linux设备驱动程序时linux系统安装,最终会生成一个文件linux内核开发,其文件扩充名为“.ko”,这个文件是可加载内核模块(LoadableKernelModulelinux内核开发,简称LKM)。下边我将详尽解释一下:
可加载内核模块(LKM):
编撰设备驱动:
编译为模块:
加载和卸载模块:
模块的生命周期:
总的来说,.ko文件是Linux设备驱动程序编译生成的二补码文件linux系统编程,它代表了一个可加载的内核模块,容许在运行的Linux系统上动态添加或移除设备驱动功能。
实现最简单的内核驱动程序hello_driver
在系统中任意一个位置创建一个文件夹,用于储存我们的hello_driver.c与Makefile文件
开始编撰hello_driver.c文件
首先须要加入必须的linux系统头文件
#include
#include
#include
“module.h”与”kernel.h”在linux内核模块中是必须的.
“init.h”在module的初始化与退出时须要被调用.
接出来编撰驱动函数,模块的载入与卸载都须要一个函数句柄,所以必需要有_init函数与_exit函数
static int __init hello_init(void) {
printk(KERN_INFO "Hello World!n");
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "Goodbye World!n");
}
```
由于我们需要将模块是否载入与卸载的信息打印出来, 所以此处用到了printk函数, 即将字符串在kernel log中打印出来, 并且这个log的等级是INFO等级.
这样, 我们就可以通过dmesg指令来查看模块是否被正确载入或卸载.

4. 最后, 我们要将模块的装载与卸载函数句柄传入
```c
module_init(hello_init);
module_exit(hello_exit);
假如这是一个即将的模块,我们也可以为其添加一些模块信息,如下
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NinoC137");
MODULE_DESCRIPTION("Hello World Linux Device Driver");
完整代码如下:
#include
#include
#include
static int __init hello_init(void) {

printk(KERN_INFO "Hello Driver!n");
return 0;
}
static void __exit hello_exit(void) {
printk(KERN_INFO "Goodbye Driver!n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NinoC137");
MODULE_DESCRIPTION("Hello World Linux Device Driver");
开始编撰Makefile文件
这儿我直接在对应linux平台本地环境下开发,所以不须要配置交叉编译的环境,Makefile便可以直接如下写出
obj-m := hello_driver.o
all: hello_driver.c
sudo make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
sudo make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
开始编译
正常情况下不会出现报错.
测试内核驱动程序Hello_Driver
经过昨晚的打算工作,在编译以后,文件夹之中都会有如下文件
开始测试驱动程序,这儿须要用到insmod与rmmod指令,即装载/卸载内核驱动模块
正常运行下是不会直接复印出信息的,所以我们须要用到sudodmesg命令来查看kernellog
可见,驱动被正确地装载与卸载了.
我们也可以使用modinfo命令来查看驱动的信息
在编译驱动晨报错Kernelconfigurationisinvalid
可能会在编译时出现这样的错误
ERROR: Kernel configuration is invalid.
include/generated/autoconf.h or include/config/auto.conf are missing.
Run 'make oldconfig && make prepare' on kernel src to fix it.
解决方式:
使用uname-r查看当前的内核版本
步入/lib/modules中对应的内核文件夹的/build文件夹之中
运行makemenuconfig,不须要做任何更改,点击save后点击load,之后exit退出即可
重新编译我们的驱动中的makefile文件,此晨报错消失,正常编译.