引子
一、设备类相关知识
设备类是虚拟的,并没有直接对应的物理实物,只是为了更好地管理同一类设备导出到用户空间而产生的目录和文件。整个过程涉及到sysfs文件系统,该文件系统是为了展示linux设备驱动模型而构建的文件系统,是基于ramfs,linux根目录中的/sysfs即挂载了sysfs文件系统。
Struct kobject数据结构是sysfs的基础,kobject在sysfs中代表一个目录,而linux的驱动(struct driver)、设备(struct device)、设备类(struct class)均是从kobject进行派生的,因此他们在sysfs中都对应于一个目录。而数据结构中附属的struct device_attribute、driver_attribute、class_attribute等属性数据结构在sysfs中则代表一个普通的文件。
Struct kset是struct kobject的容器,即Struct kset可以成为同一类struct kobject的父亲,而其自身也有kobject成员,因此其又可能和其他kobject成为上一级kset的子成员。
本文无意对sysfs和linux设备驱动模型进行展开,以后再另写文章进行分析。
二、两种创建设备文件的方式
在设备驱动中cdev_add将struct file_operations和设备号注册到系统后,为了能够自动产生驱动对应的设备文件,需要调用class_create和device_create,并通过uevent机制调用mdev(嵌入式linux由busybox提供)来调用mknod创建设备文件。当然也可以不调用这两个接口,那就手工通过命令行mknod来创建设备文件。
三、设备类和设备相关数据结构
1include/linux/kobject.h
struct kobject {
const char *name;//名称
struct list_head entry;//kobject链表
struct kobject *parent;//即所属kset的kobject
struct kset *kset;//所属kset
struct kobj_type *ktype;//属性操作接口
…
};
struct kset {
struct list_head list;//管理同属于kset的kobject
struct kobject kobj;//可以成为上一级父kset的子目录
const struct kset_uevent_ops *uevent_ops;//uevent处理接口
};
假设Kobject A代表一个目录,kset B代表几个目录(包括A)的共同的父目录。则A.kset=B; A.parent=B.kobj.
2include/linux/device.h
struct class {//设备类
const char *name; //设备类名称
struct module *owner;//创建设备类的module
struct class_attribute *class_attrs;//设备类属性
struct device_attribute *dev_attrs;//设备属性
struct kobject *dev_kobj;//kobject