I/O体系结构和设备驱动程序(二)

来源:互联网 发布:如何设置网络 编辑:程序博客网 时间:2024/06/05 02:40

2.2、kobject、kset和subsystem

 

2.2.1、kobject

设备驱动程序模型的核心数据结构是kobject,每个kobject对应于sysfs文件系统中的一个目录。

 

kobject被嵌入到一个叫做”容器”的更大对象中,容器描述设备驱动程序模型中的组件,典型的容器例子有总线、设备及驱动程序的描述符。

 

<linux/kobject.h>

struct kobject {const char* k_name; /*指向含有容器名称的字符串*/struct krefkref;     /*容器的引用计数器*/struct list_headentry;    /*用于kobject所插入的链表的指针*/struct kobject* parent;  /*指向父kobject (如果存在)*/struct kset* kset;    /*指向包含的kset*/struct kobj_type* ktype;   /*指向kobject的类型描述符*/struct sysfs_dirent* sd;      /*指向与该kobject相对应的sysfs文件的sysfs_dirent数据结构*/};

Ktype字段指向kobj_type对象,该对象描述了kobject的“类型”-------本质上,它描述的是包括kobject的容器的类型。

struct kobj_type {void (*release)(struct kobject *);    /*当kobject被释放时执行*/struct sysfs_ops* sysfs_ops;      /*指向sysfs操作表的sysfs_ops指针*/struct attribute** default_attrs; /*sysfs文件系统的缺省属性链表*/};


<linux/sysfs.h>

struct sysfs_ops {ssize_t(*show)(struct kobject *, struct attribute *,char *);ssize_t(*store)(struct kobject *,struct attribute *,const char *, size_t);};

<linux/sysfs.h>

 

/* FIXME * The *owner field is no longer used, but leave around * until the tree gets cleaned up fully. */struct attribute {const char*name;struct module*owner;mode_tmode;};

字段kref字段是一个k_ref类型结构,该字段是kobject的引用计数器。但它也可以作为kobject容器的引用计数器。

<linux/kref.h>

struct kref {atomic_t refcount;};

2.2.2、kset

函数kobject_get()和kobject_put()分别用于增加和减少引用计数器的值,如果该计数器的值等于0,就会释放kobject使用的资源,并且执行kobject的类型描述符kobj_type对象的release方法。该方法用于释放容器本身,通常只有在动态分配kobject容器时才定义该方法。

通过kset可将kobjects组织成一棵层次树。kset是同类型kobject的一个集合体-------也就是说,相关的kobject包含在同类型的容器中。

<linux/kobject.h>

/** * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem. * * A kset defines a group of kobjects.  They can be individually * different "types" but overall these kobjects all want to be grouped * together and operated on in the same manner.  ksets are used to * define the attribute callbacks and other common events that happen to * a kobject. * * @ktype: the struct kobj_type for this specific kset * @list: the list of all kobjects for this kset * @list_lock: a lock for iterating over the kobjects * @kobj: the embedded kobject for this kset (recursion, isn't it fun...) * @uevent_ops: the set of uevent operations for this kset.  These are * called whenever a kobject has something happen to it so that the kset * can add new environment variables, or filter out the uevents if so * desired. */struct kset {    /*指向kset的kobject类型描述符,该描述符被kset中所有kobject共享*/struct kobj_type*ktype;          xstruct list_headlist;            /*包含在kset中的kobject双向循环链表的首部*/spinlock_tlist_lock;struct kobjectkobj;            /*嵌入的kobject结构*/struct kset_uevent_ops*uevent_ops;};


 字段kobj是嵌入在kset中的kobject,而位于kset中的kobject,其parent字段指向这个内嵌的kobject结构。一次,一个kset是kobject集合体,但是它依赖于层次树中用于引用计数和连接的更高层kobject。这种编码效率很高,灵活性很高。

分别用于增加和减少kset引用计数器值的kset_get()和kset_put(),只需简单的调用内嵌kobject结构的kobject_get()和kobject_put()即可,因为kset的引用计数器即是其内嵌kobject的引用计数器。而且有了内嵌的kobject结构,kset数据结构可以嵌入到”容器”对象中,非常类似嵌入的kobject数据结构。最后kset可以作为其他kset的一个成员:它足以将内嵌的kobject插入到更高层次的kset中。

<linux/kobject.h>

struct kset_uevent_ops {int (*filter)(struct kset *kset, struct kobject *kobj);const char *(*name)(struct kset *kset, struct kobject *kobj);int (*uevent)(struct kset *kset, struct kobject *kobj,      struct kobj_uevent_env *env);};

2.2.3、subsystem

现在已经没有该结构体定义。但subsystem是kset的集合,一个subsystem可以包含不同类型的kset.


2.2.4、注册kobject、kset和subsystem

一般来讲,如果想让kobject、kset或subsystem出现在sysfs子树中,就必须首先注册它们。与kobject对应的目录总是出现在其父kobject的目录中,例如,位于同一个kset中的kobject的目录就出现在kset本身的目录中(kobject->parent指向其所在kset的内嵌kobject)。因此sysfs子树的结构就描述了各种已注册kobject之间以及各种容器对象之间的层次关系。

 

通常,sysfs文件系统的上层目录肯定是已注册的subsystem。

 

常用的函数有:

l  kobject_register(struct kobject * kobj)

用于初始化kobject,并将其相应的目录增加到sysfs文件系统中,在调用该函数之前,调用程序应先设置kobject中的kset字段,使它指向其父set(如果存在)。

l  kobject_unregister(struct kobject * kobj)

将kobject目录从sysfs文件系统中移走

l  kset_register(struct kset * k)

l  kset_unregister(struct kset * k)

l  subsystem_register

l  subsystem_unregister()

int subsystem_register(struct kset *s){    return kset_register(s);}void subsystem_unregister(struct kset *s){    kset_unregister(s);}


许多kobject目录都包括称为attribute的普通文件。S 

<sysfs/file.c>

/** *sysfs_create_file - create an attribute file for an object. *@kobj:object we're creating for.  *@attr:attribute descriptor. */int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)接收kobject的地址和属性描述符作为参数,并在合适目录中创建特殊文件。


Sysfs文件系统中所描述的对象间其他关系可用符号链接方式建立:sysfs_create_link()为目录中与其他kobject相关联的特定kobject创建一个符号链接。

原创粉丝点击