kobject与kset

来源:互联网 发布:工程对接软件 编辑:程序博客网 时间:2024/05/21 06:24
1 sysfs文件系统:
    
    作用: 用于向用户描述内核的驱动组织关系和内部结构。
    其中kobject 和 kset是这个文件系统的组成“砖瓦”
    
    
    2 sysfs文件系统在linux内核启动的初级阶段会被初始化。
 
二   kobject
    
    1    kobject是linux设备驱动模型的组成架构最主要元素,它实现了类似于C++的继承
    2     每一个kobject对象对应于sysfs文件系统的一个目录
 
 
 
    3    kobject在内核源码<include/linux/object.h>中被定义
 
 
    struct kobject{
           /*对象名称*/
           const char    *name;
           /*用于组织链表的指针*/
           struct list_head    entry;
           /*指向父对象的指针(父目录)*/
           struct kobject      *parent;
           /*指向所属 kset容器的指针*/
           struct kset        *kset;
           /*对象属性描述*/
           struct ktype        *ktype;
           /*在sysfs中的目录*/
           struct sysfs_dirent    *sd;
           /*引用计数*/
           struct kref        kref;
           unsigned int     state_initialized:1;
           unsigned int     state_in_sysfs:1;
           unsigned int     state_add_uevenr_sent:1;
           unsigned int     state_remove_uevent_sent:1;
           unsigned int     state_uevent_suppress:1;
    }
     
     
    注:如果kboject属于某个kset那么它的变化就可以通过这个kset来向用户空间发送消息。
    其中state_uevent_suppress标志位用于决定是否向用户空间发送消息。
     
     
    4  用法;kobject嵌入某个对象当中。比如在字符设备对象当中
        
        struct cdev{
            struct kobject    *kobj;
            struct module    *owmer;
            const  struct file_operation *ops;
            struct list_head list;
            dev_t dev;
            unsigned int count;
        }
        
        
    5 相关函数
     
        kobject_set_name(struct kobject *kobj,const char *fmt,......);
        用于设置对象名称
        
        kobject_init用于初始化kobject,在<lib/kobject.c>中。
        主要代码如下:
         
        void kobject_init(struct kobjcet* kobj,struct kobj_type *ktype)
        {
            ......
            kobject_init_internal(kobj);
            kobj->ktype = ktype;
            return ;
        }
         
        在kobject_init中做两件事:1 调kobject_init_internal实现大部分初始化 2 指定ktype
         
        kobject_init_internl在<lib/kobject.c>中实现,主要代码如下。
         
        kobject_init_inernal(struct object *kobj)
        {
            if(!kobject)
                return;
                
            kref_init(kobj->kref);
             
            INIT_LIST_HEAD(&kobject->entry);
             
            kobj->state_in_sysfs = 0 ;
            kobj->state_add_uevent_sent = 0;  
            kobj->state_remove_uevent_sent= ;  
            lobj->state_initialized = 1;
                
        }
         
         
        int kobject_add(struct kobject* kobj,struct kobj *parent,const char *fmt......)
        这个函数可以实现kobject之间的层次关系,并且将这个kobject添加到sysfs当中去。
         
        这个函数将parent传递给kobj后调用kobject_add_initernl()
         
        在<lib/kobject.c>中实现。
         
        /*设置好parent变量 然后创建目录*/
        int kobject_add_internal(struct kobject *kobj)
        {
            ...
            /*先取得kobj的parent成员*/
            parent = kobject_get(&kobject->parent);
            /*在kboj属于某个kset的情况下 如果其parent为NULL
              就将其parent设为kset的kobj
            */
            if(kobj->kset){
                
                if(!parent){
                     
                    parent = kobject_get(&kobj->kset->kobj);
                     
                    kobj_kset_jion(kobj);
                     
                    kobj->parent = parent;
                     
                    }
                }
                
            ....
                    
            }
            
        接下来kobject_add_internal还会调用sysfs_create_dir(struct kobject *kobj)
        用来创建目录。在<fs/sys/dir.c>中实现
         
        sysfs_create_dir(struct kobject *kobj){
            
             ...
             if(kobj->parent)
                 parent_sd = kobj->parent->sd;
             else
                 parent_sd = &sysfs_root;
             ...
              
             error = creat_dir(kobj,parent_sd,type,ns,kobject_name(kobj),&sd);
             if(!error)
                 kobj->sd = sd;
             return error;
            }
         
        注:在sysfs文件系统中一个目录的数据结构是sd实例。
        一个kobj对象都会嵌入一个sd成员,所以一个kobj对象就是对应一个目录
         
         
       内核中,将init和add两个函数合并之后得到kobject_init_and_add(struct kobject *kobj,struct kobj_type *ktype,
                                          struct kobject *parent,const char *fmt,...)函数。
                                           
        
        
        
       struct kobject *kobject_creat()用于分配并且初始化一个kobject
        
       实现如下:
        
        struct kobject *kobject_creat()
        {
            struct kobject *kobj;
             
            kobj = kzalloc(sizeof(*kobj),GFP_KERNEL);
            if(!kobj)
             return NULL;
            
            kobject_init(kobj,&dynamic_kob_ktype);
            
            return kobj;
        }
         
        显然,如果我们要重新制定自己的kobject type那么我们需要再调用其他函数。
         
   
   
   
 三 kboject的属性。
 
 在kobject中有一个kob_type类型的成员ktype 用于描述kobject的属性。
 在inlcude/linux/kobject.h 中定义如下;
 
 
 
 
 
四  kset
 kset是一个管理kobj的数据结构,它将kobj组成一个链表来管理,一旦这些链表中的kobj发生改变,
 kset就首先调用操作集中的filter函数,如果函数通过,那么就向用户空间进行通知广播。
 
kset的定义如下:
 
struct kset
{
    struct list_head list ;
    spinlock_ list_lock;
    struct kobject kobj;
 
    const struct kset_uevent_ops *uevent_ops;
 
}
 
主要操作函数有:
 
1 kset_register(struct kset *k)
{
     
    int err;
    if(!k)
    return -EINVAL;
     
    kset_init(k);
    err = kobject_add_internal(&k->kobj);
     
    if(err)
      return err;
       
    kobject_uevent(&k->kobj,KOBJ_ADD);/*通知内核有kset的kboj被添加*/
}
 
2 creat_and_add(const char *name,const struct kset_uevent_ops *uevent_ops,
        struct kobject *parent_kobj);
        
用于创建一个kset并加入sysfs中

0 0
原创粉丝点击