Linux kernel 之 kobject

总听有人说 Linux kernel 拥有一团无比巨大看似杂乱无章其实有迹可循的链表,今天参考一下其他大牛的相关资料记录一下。


  • kset 结构体

    151 /**                                                                             
    152  * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
    153  *                                                                              
    154  * A kset defines a group of kobjects.  They can be individually                
    155  * different "types" but overall these kobjects all want to be grouped          
    156  * together and operated on in the same manner.  ksets are used to              
    157  * define the attribute callbacks and other common events that happen to        
    158  * a kobject.                                                                   
    159  *                                                                              
    160  * @list: the list of all kobjects for this kset                                
    161  * @list_lock: a lock for iterating over the kobjects                           
    162  * @kobj: the embedded kobject for this kset (recursion, isn't it fun...)       
    163  * @uevent_ops: the set of uevent operations for this kset.  These are          
    164  * called whenever a kobject has something happen to it so that the kset        
    165  * can add new environment variables, or filter out the uevents if so           
    166  * desired.                                                                     
    167  */                                                                             
    168 struct kset {                                                                   
    169     struct list_head list;       // 这里边包含了这个 kset 所有的 kobject                                               
    170     spinlock_t list_lock;                                                       
    171     struct kobject kobj;         // 一个嵌入在里面的kobject                                               
    172     const struct kset_uevent_ops *uevent_ops;     // 里面包含热拔插事件发生时的响应操作                     
    173 };                                                                              

* #### kobject 结构体
    //  include/linux/kobject.h
     63 struct kobject {                                                                
     64     const char      *name;       // 名字                                              
     65     struct list_head    entry;   // 连接到 kset 建立层次结构                                       
     66     struct kobject      *parent;  // 上一个节点                                              
     67     struct kset     *kset;        // 指向所属的 kset                                             
     68     struct kobj_type    *ktype;   // 指向所属的 ktype                                              
     69     struct kernfs_node  *sd; /* sysfs directory entry */     //  文件系统内的sysfs 的node                    
     70     struct kref     kref;         // 引用计数                                             
     71 #ifdef CONFIG_DEBUG_KOBJECT_RELEASE                                             
     72     struct delayed_work release;                                                
     73 #endif                                                                          
     74     unsigned int state_initialized:1;     //  初始化状态,只占 1 个位的空间,应用了位域                     
     75     unsigned int state_in_sysfs:1;                                             
     76     unsigned int state_add_uevent_sent:1;                                       
     77     unsigned int state_remove_uevent_sent:1;                                    
     78     unsigned int uevent_suppress:1;                                             
     79 };                                                                              

* #### kobj_type 结构体
    116 struct kobj_type {                                                              
    117     void (*release)(struct kobject *kobj);                                      
    118     const struct sysfs_ops *sysfs_ops;                                          
    119     struct attribute **default_attrs;                                           
    120     const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
    121     const void *(*namespace)(struct kobject *kobj);                             
    122 };                                                                              


* #### kobject_init - initialize a kobject structure : 初始化
    // lib/kobject.c
    // 318  * This function will properly initialize a kobject such that it can then       
    // 319  * be passed to the kobject_add() call.   等下还有kobject_add()                                      
    // 321  * After this function is called, the kobject MUST be cleaned up by a call      
    // 322  * to kobject_put(), not by a call to kfree directly to ensure that all of      
    // 323  * the memory is cleaned up properly.      必须用 kobject_put 去释放,而不是 kfree
     325 void kobject_init(struct kobject *kobj, struct kobj_type *ktype)                
     326 {                                                                               
     327     char *err_str;                                                              
     328                                                                                 
     329     if (!kobj) {                                                                
     330         err_str = "invalid kobject pointer!";                                   
     331         goto error;                                                             
     332     }                                                                           
     333     if (!ktype) {                                                               
     334         err_str = "must have a ktype to be initialized properly!
";            
     335         goto error;                                                             
     336     }                                                                           
     337     if (kobj->state_initialized) {                                              
     338         /* do not error out as sometimes we can recover */                      
     339         printk(KERN_ERR "kobject (%p): tried to init an initialized "           
     340                "object, something is seriously wrong.
", kobj);                
     341         dump_stack();                                                           
     342     }                                                                           
     343
     344     kobject_init_internal(kobj);       // 初始化有关的成员                                                                                                                    
     345     kobj->ktype = ktype;                                                        
     346     return;                                                                     
     347                                                                                 
     348 error:                                                                          
     349     printk(KERN_ERR "kobject (%p): %s
", kobj, err_str);                       
     350     dump_stack();                                                               
     351 }                                                                               
     352 EXPORT_SYMBOL(kobject_init);                                                    
    // kobject_init_internal 一些属性的初始化
     187 static void kobject_init_internal(struct kobject *kobj)                         
     188 {                                                                               
     189     if (!kobj)                                                                  
     190         return;                                                                 
     191     kref_init(&kobj->kref);     // 设置计数为1                                                
     192     INIT_LIST_HEAD(&kobj->entry);                                               
     193     kobj->state_in_sysfs = 0;                                                   
     194     kobj->state_add_uevent_sent = 0;                                            
     195     kobj->state_remove_uevent_sent = 0;                                         
     196     kobj->state_initialized = 1;        // 设置初始化状态                                        


* #### 通过总线注册函数解析 kset , kobjectd , ktype 这些结构体的关系。
    // drivers/base/bus.c
    // 这里先将 两个变量作为全局变量
      25 /* /sys/devices/system */                                                       
      26 static struct kset *system_kset;
     178 static struct kset *bus_kset;
    // 入口函数
    1278 int __init buses_init(void)                                                      
    1279 {            // kset 创建和添加  , 名字为"bus"  "bus事件操作" “父project 为空”                                                           
    1280     bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);               
    1281     if (!bus_kset)                                                              
    1282         return -ENOMEM;                                                         
    1283                                                                                 
    1284     system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);     
    1285     if (!system_kset)                                                           
    1286         return -ENOMEM;                                                         
    1287                                                                                 
    1288     return 0;                                                                   
    1289 }                                                                               
    // kset_create_and_add
    // 头文件 include/linux/kobject.h
    178 extern struct kset * __must_check kset_create_and_add(const char *name,         
    179                         const struct kset_uevent_ops *u,                        
    180                         struct kobject *parent_kobj);   
    
    // 源代码  lib/kobject.c
     936 struct kset *kset_create_and_add(const char *name,                              
     937                  const struct kset_uevent_ops *uevent_ops,                      
     938                  struct kobject *parent_kobj)                                   
     939 {                                                                               
     940     struct kset *kset;                                                          
     941     int error;                                                                  
     942                   // 名字为"bus" ,申请一段空间并初始化相关kset 属性                                                                     
     943     kset = kset_create(name, uevent_ops, parent_kobj);                          
     944     if (!kset)                                                                  
     945         return NULL;                                                            
     946     error = kset_register(kset);  // 注册                                            
     947     if (error) {                                                                
     948         kfree(kset);                                                            
     949         return NULL;                                                            
     950     }                                                                           
     951     return kset;                                                                
     952 }                                                                               
    //  lib/kobject.c
    //  kset_register
     809 int kset_register(struct kset *k)                                               
     810 {                                                                               
     811     int err;                                                                    
     812                                                                                 
     813     if (!k)                                                                     
     814         return -EINVAL;                                                         
     815     // 初始化                                                                            
     816     kset_init(k);                                                               
     817     err = kobject_add_internal(&k->kobj);   // 接下                                    
     818     if (err)                                                                    
     819         return err;                                                             
     820     kobject_uevent(&k->kobj, KOBJ_ADD);                                         
     821     return 0;                                                                   
     822 }                                                                               
     823 EXPORT_SYMBOL(kset_register);                                                   
    // kset 初始化
     767 void kset_init(struct kset *k)                                                  
     768 {   // 这个在上面已经跟过了
      // 最主要是初始化了 state_initialized = 1                                                                          
     769     kobject_init_internal(&k->kobj);                                            
     770     INIT_LIST_HEAD(&k->list); // 设置为链表头                                                
     771     spin_lock_init(&k->list_lock);                                              
     772 }                                                                               
    // kobject_add_internal
     200 static int kobject_add_internal(struct kobject *kobj)                           
     201 {                                                                               
     202     int error = 0;                                                              
     203     struct kobject *parent;                                                     
     204                                                                                 
     205     if (!kobj)                                                                  
     206         return -ENOENT;                                                         
     207                                                                                 
     208     if (!kobj->name || !kobj->name[0]) {                                        
     209         WARN(1, "kobject: (%p): attempted to be registered with empty "         
     210              "name!
", kobj);                                                  
     211         return -EINVAL;                                                         
     212     }                                                                           
     213                                                                                 
     214     parent = kobject_get(kobj->parent);                                         
     215                                                                                 
     216     /* join kset if set, use it as parent if we do not already have one */      
     217     if (kobj->kset) {                                                           
     218         if (!parent)                                                            
     219             parent = kobject_get(&kobj->kset->kobj);                            
     220         kobj_kset_join(kobj);                                                   
     221         kobj->parent = parent;                                                  
     222     }                                                                           

原文地址:https://www.cnblogs.com/chenfulin5/p/6808881.html