- 论坛徽章:
- 0
|
在linux里,可以从两种不同的视角来看待设备。一种是从操作系统的角度,一种是从用户的角度。从内核的角度来看,各个设备必须挂接在总线上,由驱动程序驱动。相应的数据结构要体现出设备和设备驱动程序以及总线之间的关系;从用户角度来看,设备也是文件,因此在/sysfs/bus/?/?, /dev/?等目录下应该有对应的文件来表示设备。
因此设备驱动模型的数据结构设计需要从上述两个方面体现。从总的方面来说,可以把各种数据结构分为两种:设备、驱动等实体对应的数据结构,如struct driver;还有就是这些实体之间的层次关系,如struct kobject。为了讨论方便还是先介绍这些数据结构。
kobject
kobject是最基本的数据结构,如果按照面向对象的思想来说,它是基类。各种实体的相互关系,最终都是由该结构来衔接的。每个要体现相互关系的数据结构都要内嵌一个kobject类型的变量。
struct kobject {
char * k_name; /*指向name的指针*/
char name[KOBJ_NAME_LEN]; /*名字*/
atomic_t refcount; /*引用计数*/
struct list_head entry; /*在所挂到链表的连接体*/
struct kobject * parent; /*父结点*/
struct kset * kset; /*指向所属的kset*/
struct kobj_type * ktype;
struct dentry * dentry; /*目录项*/
};
在kobject的成员中,entry、parent和kset体现了层次关系,dentry主要是用来和文件系统联系用的。而ktype是用来和用户空间打交道的,包括属性的显示以及空间的释放,结构体如下:
struct kobj_type {
void (*release)(struct kobject *);
struct sysfs_ops * sysfs_ops;
struct attribute ** default_attrs;
};
struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *,char *);
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
};
show和store就是用来显示和存储属性的方法。
kset
kset是kobject的集合。通过一个双向循环链表把属于同一kset的kobject连在一起。
struct kset {
struct subsystem * subsys; /*指向所属的subsystem*/
struct kobj_type * ktype;
struct list_head list; /*连接属于同一kset的kobject*/
struct kobject kobj;
struct kset_hotplug_ops * hotplug_ops; /*与热插拔相关的操作*/
};
kset里包含kobject型变量,就是用它来体现层次关系以及别的基础功能,包括引用计数等。假设obj_a属于某个ket—kset_a,那么
obj_a.kset = *kset_a
obj_a.parent = *(kset_a.obj)
而且obj_a会添加到kset_a的list中。
subsystem
subsystem比kset更高一级。一个subsystem包括多个kset。
struct subsystem {
struct kset kset;
struct rw_semaphore rwsem;
};
由subsystem和kset的结构定义可以看出,无法从subsystem找到属于它的所有kset。因为只有kset的subsys指针可以找到subsystem,而subsystem没有对应的成员变量可以访问到kset。也许大家会说subsystem里包含kset,而kset里又含有list,那么可以把属于同一个subsystem的kset挂入到该list。但是我们前面说过,kset里的list是用来连接kobject用的,那么就无法再作为它用了。
今天就先分析这几种不同数据结构。至于这些数据结构为什么要这样设计,则得配合具体的驱动程序来分析。等有时间就做个具体例子的分析。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/17192/showart_335016.html |
|