linux字符设备驱动框架详解

相关概念

内核模块

ko 文件在数据组织形式上是 ELF(Excutable And Linking Format) 格式,是一种普通的可重定位目标文件。这类文件包含了代码和数据,可以被用来链接成可执行文件或共享目标文件,静态链接库也可以归为这一类。

模块的加载与卸载

加载

首先 insmod 会通过文件系统将 .ko 模块读到用户空间的一块内存中,然后执行系统调用

sys_init_module() 解析模组 ,重定位代码到合适的位置,执行ko的init操作。

卸载

输入指令 rmmod,最终在系统内核中需要调用 sys_delete_module

进行实现。

具体过程如下:先从用户空间传入需要卸载的模块名称,根据名称找到要卸载的模块指针,确保我们要卸载的模块没有被其他模块依赖,然后找到模块本身的 exit 函数实现卸载。

设备号

dev_t 用来表示设备编号, dev_t 是一个 32 位的数,其中,高 12 位表示主设备号,

低 20 位表示次设备号

//根据设备的设备号来获取设备的主设备号

#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))

//提取设备的次设备号

#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))

//将主次设备号合并成设备号

#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))

cdev

以主设备号为 cdev_map 编号,使用哈希函数 f(major)=major%255 来计算组数下标 (使用哈希函数是为了链表节点尽量平均分布在各个数组元素中,提高查询效率);每个主设备号可包含一系列不同次设备号的字符设备节点。主设备号冲突, 则以次设备号为比较值来排序链表节点。

字符驱动框架

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name)

动态分配count个设备号,设备名为name

cdev_init(struct cdev *cdev, const struct file_operations *fops)

关联字符设备结构体cdev与文件操作结构体file_operations

cdev_add(struct cdev *p, dev_t dev, unsigned count)

添加count个设备至cdev_map散列表中

也可使用register_chrdev一步到位

此时当使用时,需要使用mknod命令创建一个设备节点。当然,也可以先创建类(表示一种类型的设备、/sys/class目录下创建一个新文件夹),再在类下创建设备(/sys/class/new_class/new_device),这样系统便会自动创建设备节点。实际上就是创建了一个设备节点 inode 结构体 ,表示一个具体设备文件(操作这个文件就相当于操作设备,操作的地址是设备寄存器地址)

对于一个LED设备,sysfs可以有两个节点来描述该外设:

1、/sys/class/led_class目录下的节点。这是从high level角度看该LED设备的接口。这里我们可以把一个属于LED设备的属性放到这个目录下,例如:LED颜色、闪烁的频率、占空比等,只要是led class,任何设备都是有这些属性的(无论是接到platform bus还是接到I2C bus)。

2、/sys/devices/virtual/led_class目录下的节点。这个节点是和物理拓扑有关了。其实对于device_create(哪一类设备, 物理拓扑参数,…) 而言,如果你不传递物理拓扑参数(传入NULL),那么设备模型会统一放到virtual的目录下。这个目录保存的属性文件和/sys/class/led_class目录下的是不一样的,这里的属性文件更多的是关注作为某个总线外设的属性。我们可以把这个LED变得复杂些,例如是一个USB接口的LED设备(当然,实际上我是没有见过这样的设备,呵呵~~最多是I2C的LED设备),这时候,这个目录下就会保存这样的属性文件:该设备有多少个endpoint、interface的数目,类别等,而这些属性是和USB总线有直接的关系。

sysfs中所有的目录以及目录下的文件都对应内核中的一个struct kobj实例。

bus目录中所有的子目录都对应内核中的一个struct bus_type实例。

class目录中所有的子目录对应内核中的一个struct class实例

devices目录中的所有目录以及子目录都对应一个struct device实例

猜你喜欢

转载自blog.csdn.net/qq_52353238/article/details/129440056