前言
Linux内核架构非常庞大,为了避免修改轮子要重新造车的情况,诞生了模块(module),也叫驱动,驱动文件一般以ko结尾,所以也被写作“驱动ko”,详细内容这里不介绍
本文主要列出一个简单的demo
源文件
驱动相关的源文件最简单的结构需要两个,一个c代码文件,另一个是makefile
一般情况下,两个文件在同一个目录下,至于放在哪里,这个无所谓
hello work c code123456789101112131415161718192021#include
模块加载当模块被加载的时候会执行init函数,也就是通过module_init()方法注册的函数,而且函数需要有__init标记,一般用来做模块的初始化,这里如果卡住,则会导致驱动加载命令卡住,返回0表示加载成功。
模块卸载模块被卸载的时候会执行exit函数,也就是通过module_exit()方法注册的函数,函数需要有__exit标记,一般用来做资源释放和一些打印信息等
模块声明可以通过标记的形式进行声明一些信息:
声明
说明
MODULE_LICENSE
声明许可证:一般包括 “GPL”、“GPL v2”、“GPLand additional rights”、“Dual BSD/GPL”、“Dual
MODULE_AUTHOR
作者信息,姓名,邮箱等
MODULE_DESCRIPTION
驱动说明
MODULE_VERSION
版本号
MODULE_DEVICE_TABLE
设备列表
MODULE_ALIAS
别名
makefile
Ubuntu 24.04 x86_64平台
1234567891011KVERS := /lib/modules/$(shell uname -r)/buildCURDIR := $(shell pwd)# 这里的hello.o是对应c文件hello.cobj-m := hello.obuild: make -C $(KVERS) M=$(CURDIR) modulesclean: make -C $(KVERS) M=$(CURDIR) clean
该Makefile文件中,build和clean下的内容行开头的空隙必须为
-C选项将工作目录转到$(KVERS)指定的目录下,该目录下有内核顶层的Makefile
M=选项是把当前路径,传递到内核顶层的Makefile,要求在建立内核模块前,回到指定的路径
编译直接使用make命令就可以进行编译,如果是普通用户,需要使用sudo进行提权
使用
通过insmod或者modprobe进行驱动的加载
通过rmmod或者modprobe -r进行驱动的卸载
使用时可能会报错
Key was rejected by service这是因为做出的驱动默认是没有签名的,如果环境开了强制签名校验,则不允许通过我这里是因为bios中开启了Secure Boot,重启进入BIOS将其关闭就可以了当然如果给该驱动进行签名,也可以解决问题,可以参考这篇文章:Ubuntu下给驱动签名
参考
linux学习笔记(五)编译内核模块生成ko驱动文件
ubuntu内核模块编译