内核模块驱动开发
内核模块开始学习前,一定是最先接触到内核模块三要素(面试),驱动入口、驱动出口和协议的遵循。
1.内核模块三要素(面试)//修饰模块化驱动的入口函数module_init(demo_init);//修饰模块化驱动的出口函数module_eixt(demo_exit);//遵循GPL开源协议MODULE_LICENSE("GPL");记住就像没有那么多为什么
这个三要素没有那么多为什么,记住就可以了,每一个驱动模块都要遵循。
这里会涉及到三个宏,module_init、module_exit、MODULE_LICENSE。我们到内核里面去找一下他们的原型,
module_init 是 linux kernel 绝大多数模块的起始点,我们所熟悉的应用程序都是从一个 main() 函数开始运行的,但内核模块都是从module_init开始的,向系统申请资源。
有开始就有结束,与 module_init 对应的就是 module_exit 。module_exit 负责进行一些和init反向的活动,例如:
- init 是注册驱动,exit 就是注销驱动
- init 是申请资源,exit 就是释放资源
- init 是创建节点,exit 就是销毁节点
注意exit中活动的顺序,应该对应 init 中活动的逆序
MODULE_LICENSE是固定的,意思是要遵循什么开源协议,使用是GPL
下面的是小例子
//头文件#include <linux/init.h>#include <linux/module.h>1.1.1:入口函数函数(向系统申请资源)static int __init demo_init(void){//__init 用于修饰dome_init函数,作用是把这个函数放到init代码中//__init被定义在init.h中 #define __ init __sertion(.init.text)printk("exit demo_init")}1.1.2:出口函数(释放向内核申请的资源static void __exit demo_exit(void){printk("exit demo_exit")}1.1.3:许可证(遵循GPL开源协议)//修饰模块化驱动的入口函数module_init(demo_init);//修饰模块化驱动的出口函数module_eixt(demo_exit);//遵循GPL开源协议MODULE_LICENSE("GPL");记住就像没有那么多为什么
上图以demo函数做一个例子,其中的 static 和 __init 不是必须的:
- static 是为了函数不被模块外部错误引用(注意不可使用内联定义)
- __init 是告诉系统这个是用来初始化的函数,运行后不必再保留在内存中
- 入口格式:int (*) (void)
- 出口格式:void (* ) (void)