01 驱动组成的三大部分
一个内核驱动主要分为三大部分:
module_init()
——入口- 编写初始化函数并将函数名传入入口函数
- 初始化函数的格式为
int __init func_name(void)
- 即返回值为
int
型,参数类型为void
,函数名前的__init
表示将其加载到init段。
- 初始化函数的格式为
- 编写初始化函数并将函数名传入入口函数
module_exit()
——出口- 编写驱动销毁函数并将函数名传入出口函数,释放资源。
- 销毁函数的格式为
void __exit func_name(void)
- 返回值为
void
,参数类型为void
,函数名前的__exit表示将其加载到exit
段。
- 销毁函数的格式为
- 编写驱动销毁函数并将函数名传入出口函数,释放资源。
MODULE_LECENSE("GPL")
——所遵循的证书- 标准操作
02 所需库及Makefile
调用以上三个函数需要包含两个内核库
#include <linux/init.h>
#include <linux/module.h>
且这两个库需要根据内核版本来配置,使用uname -r
查看当前内核版本。
root@ubuntu:~/Desktop# uname -r
4.15.0-54-generic
则在ubuntu18.04下对应的编译路径为/usr/src/linux-headers-4.15.0-54-generic/
创建Makefile文件如下,一定要注意M要大写!!!!!!。
obj-m := first_module.o
PWD := $(shell pwd)
KERNEL_INFO := $(shell uname -r)
KERNEL_LIB := /usr/src/linux-headers-$(KERNEL_INFO)
all:
make -C $(KERNEL_LIB) M=$(PWD) modules
clean:
make -C $(KERNEL_LIB) M=$(PWD) clean
03 Show me the code
对应的first_module.c
文件与Makefile在同一目录
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
// init function
int __init test_init(void)
{
printk("<___My first module was put on the kernel.___>\n");
return 0;
}
// exit function
void __exit test_cleanup(void)
{
printk("<___My first module was moved of.___>\n");
}
module_init(test_init);
module_exit(test_cleanup);
MODULE_LICENSE("GPL");
04 结果
在Makefile所在目录执行make
,结果如下。
root@ubuntu:~/Desktop# make
make -C /usr/src/linux-headers-4.15.0-54-generic M=/home/ttyf/Desktop modules
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-54-generic'
CC [M] /home/xxx/Desktop/first_module.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/xxx/Desktop/first_module.mod.o
LD [M] /home/xxx/Desktop/first_module.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-54-generic'
-
执行
dmesg -c
查看未加载我们的驱动的日志,-c
表示查看后清除日志。 -
执行
insmode first_module.ko
,将我们的驱动加载到内核。 -
执行
dmesg
查看加载我们的模块后init函数中的输出。 -
执行
rmmod first_module
,将我们的模块卸载。 -
执行
dmesg
查看卸载时,模块的输出。 -
执行
make clean
清理。
结果如下:
root@ubuntu:~/Desktop# insmod first_module.ko
root@ubuntu:~/Desktop# dmesg
[ 3308.978497] <___My first module was put on the kernel.___>
root@ubuntu:~/Desktop# rmmod first_module
root@ubuntu:~/Desktop# dmesg
[ 3308.978497] <___My first module was put on the kernel.___>
[ 3324.548336] <___My first module was moved of.___>
root@ubuntu:~/Desktop# make clean
make -C /usr/src/linux-headers-4.15.0-54-generic M=/home/ttyf/Desktop clean
make[1]: Entering directory '/usr/src/linux-headers-4.15.0-54-generic'
CLEAN /home/ttyf/Desktop/.tmp_versions
CLEAN /home/ttyf/Desktop/Module.symvers
make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-54-generic'