Linux下编译驱动ko

admin
2025-11-14 10:00:00

前言

Linux内核架构非常庞大,为了避免修改轮子要重新造车的情况,诞生了模块(module),也叫驱动,驱动文件一般以ko结尾,所以也被写作“驱动ko”,详细内容这里不介绍

本文主要列出一个简单的demo

源文件

驱动相关的源文件最简单的结构需要两个,一个c代码文件,另一个是makefile

一般情况下,两个文件在同一个目录下,至于放在哪里,这个无所谓

hello work c code123456789101112131415161718192021#include #include static int __init hello_init(void){ printk("hello world start \n"); return 0;}static void __exit hello_exit(void){ printk("hello world rmmod \n ");}module_init(hello_init);module_exit(hello_exit);MODULE_AUTHOR("zhuizhutime");MODULE_VERSION("0.1");MODULE_LICENSE("GPL");MODULE_DESCRIPTION("test hello world");

模块加载当模块被加载的时候会执行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内核模块编译