注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

liuyue18301的个人主页

追逐梦想 光辉岁月

 
 
 

日志

 
 

linux kobject kset  

2011-05-27 09:55:19|  分类: linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

kobject, kobj_type, kset简介

kobject是linux设备模型中最基本的结构。要说明的是,linux内核虽然由C语言编写,但是内核在实现时,到处都体现出开发者面向对象的思想。所以,kobject也可以理解为所有驱动对象的基类。后面用到的驱动对象,几乎都是kobject的派生类。作为基类的kobject并不关心自己是如何实现的,所以,在内核中,没有用kobject直接定义的变量,kobject只是作为一个抽象的基类而存在。一般都是将kobject嵌入到另一个结构,这个结构就可以看做是kobject的一个子类。而kobject的子类会比较关心kobject的属性和方法。

kobject包含一个名字和一个引用计数器,这个引用计数器会记录由kobject派生的内核对象被引用的次数。所以,一个结构最多只能包含一个kobject对象,否则,该结构的引用计数会乱套的。

上面提到,关心kobject实现的并不是kobject自身而是包含kobject的结构,所以当不同的结构包含kobject后,kobject的属性会不同,kobject销毁时所做的操作会不同,kobject所表现出的类型也会不同。所以,kobject中包含了一个叫作kobj_type的结构。kobj_type的目标就是为不同类型的kobject提供不同的属性以及销毁方法。

有时候,某个设备的可能具有多个kobject的子类对象,或者某些设备具有相同的特性,为了便于管理,应该把这些对象统一放入一个容器中。这里要用到的容器就是kset。kset只是kobject的一个集合。对应到linux文件系统中,一个kset就是/sys下的一个文件夹。

 

kobject详细介绍

先看看kobject的结构:

struct kobject {

    const char    *name;            //可以给kobject起一个名字

    struct list_head  entry;

    struct kobject       *parent;   //kobject的父指针

    struct kset       *kset;            //kobject所属的kset

    struct kobj_type  *ktype;

    struct sysfs_dirent  *sd;              //kobject在sysfs中的层次结构,关于sysfs这里不做讨论

    struct kref       kref;             //引用计数

    unsigned int state_initialized:1;

    unsigned int state_in_sysfs:1;

    unsigned int state_add_uevent_sent:1;

    unsigned int state_remove_uevent_sent:1;

    unsigned int uevent_suppress:1;

};

kobject的操作:

extern int kobject_set_name(struct kobject *kobj, const char *name, ...)

               __attribute__((format(printf, 2, 3)));

extern int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,

                va_list vargs);

上两个函数为设定kobject的名字。虽然从上面的结构定义中可以看到kobject的名字就是成员name所指向的字符串,但为kobject设定名字时,还是函数kobject_set_name,这样可以提高代码的可移植性。

 

static inline const char *kobject_name(const struct kobject *kobj)

{

    return kobj->name;

}

 

extern void kobject_init(struct kobject *kobj, struct kobj_type *ktype);

此函数初始化kobject中的entry,kref,将state_in_sysfs设为0,state_add_uevent_sent设为0,state_remove_uevent_sent设为0,state_initialized设为1,并根据传入的ktype设定kobj->ktype,而且ktype不能为空。

 

extern int __must_check kobject_add(struct kobject *kobj,

                  struct kobject *parent,

                  const char *fmt, ...);

此函数将一个已初始化好的kobject加入系统,第一个参数是需要加入的kobject,第二个参数是kobject的父结点,第三个参数是kobject的名字。若parent为空,且kobj->kset不为空,则将kobj->prent设为&kobj->kset->kobj。此函数的流程图如下:

 

 

 

extern int __must_check kobject_init_and_add(struct kobject *kobj,

                       struct kobj_type *ktype,

                       struct kobject *parent,

                       const char *fmt, ...);

从名字就可以看出来,这个函数是kobject_init和kobject_add的组合

 

extern void kobject_del(struct kobject *kobj);

此函数只是将kobject从sysfs和kset中去掉,并不是删除kobject,删除kobject得靠kobject->ktype->release才行。kobject_del在把kobject从kset中去掉后,会把kset的引用值减1。

 

extern struct kobject * __must_check kobject_create(void);

动态分配一个kobject,将kobject的ktype设为&dynamic_kobj_ktype后,并初始化之。

 

extern struct kobject * __must_check kobject_create_and_add(const char *name,

                     struct kobject *parent);

从名字就可以看出来,这个函数是kobject_create和kobject_add的组合。

以上两个函数的流程图如下:

 

 

 

extern int __must_check kobject_rename(struct kobject *, const char *new_name);

此函数可以为一个已经添加到sysfs中的kobject重命名,同时也会改变kobject在sysfs中对应的文件名。此函数在重命名之前会先把kobject的引用值加1,在改完名后,会再把kobject的引用值减1。

 

extern int __must_check kobject_move(struct kobject *, struct kobject *);

此函数可以改变一个kobject的parent,并同时更新kobject在sysfs中的路径,更换完parent之后,函数会把kobject以前的parent的引用值减1。

 

extern struct kobject *kobject_get(struct kobject *kobj);

此函数为kobject的引用值加1。

 

extern void kobject_put(struct kobject *kobj);

此函数为kobject的引用值减1,若引用值减为0,则销毁此kobject。

上面这两个函数的流程图如下:

 

 

 

extern char *kobject_get_path(struct kobject *kobj, gfp_t flag);

获取kobject在sysfs中的路径。

 

 

ktype详细介绍

 

struct kobj_type {

    void (*release)(struct kobject *kobj);     //kobject销毁时所调用的函数,由kobject_put调用

    const struct sysfs_ops *sysfs_ops;         //对于attribute的操作

    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);

};

kobj_type中的后两个成员表示了kobject在sysfs中的各个属性,及各个属性的操作方法。

需要说明的是,每一个kobject都必须有一个release函数,而已每个kobject不能在release函数被调用之前被销毁。release的作用是清除为kobject分配的内存空间,不过在release被调用时,kobject->name是有效的,但是,release函数不能改变name,因为name的释放是在函数kobject_cleanup中做的。

 

kset详细介绍

 

struct kset {

    struct list_head list;       //此链表中保存了kset中所有的kobject

    spinlock_t list_lock;        //当遍历list时,使用的锁

    struct kobject kobj;         //居然递归嵌套,我晕。。。。

    const struct kset_uevent_ops *uevent_ops;  //暂时不讨论uevent

};

kset关联的操作:

extern void kset_init(struct kset *kset);

初始化kset中各个成员。

 

extern int __must_check kset_register(struct kset *kset);

此函数首先将kset加入sysfs(kset加入sysfs是通过kset中的成员kobject实现的,其实加入sysfs的不是kset本身,而是kset的成员kobject,可以通过kobject和container_of找到kset)然后发出一个KOBJ_ADD的uevent。

 

extern struct kset * __must_check kset_create_and_add(const char *name,

                     const struct kset_uevent_ops *u,

                      struct kobject *parent_kobj);

此函数只是kset_create和kset_register的组合,其中kset_create会动态生成一个kset,并将其初始化。如果想简单地生成一个kset并将其加入系统,可以调用此函数。

以上三个函数的流程图如下:

 

 

 

extern void kset_unregister(struct kset *kset);

此函数将kset从sysfs中移出,也就是将kset的成员kobject从sysfs中移出。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mm350670610/archive/2010/09/19/5895561.aspx

  评论这张
 
阅读(1079)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018