zoukankan      html  css  js  c++  java
  • 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     }                                                                           
    
    
  • 相关阅读:
    bootstrap 导航学习
    算法学习1-插入排序
    管道输入输出流
    1+2*2+3*3+4*4+...+n*n计算
    maven安装for eclipse kepler
    javascript学习7-细节总结
    Git Fetch failed解决办法
    前端学习笔记
    TIOBE 编程语言排行榜
    用VS2012创建和使用WebService
  • 原文地址:https://www.cnblogs.com/chenfulin5/p/6808881.html
Copyright © 2011-2022 走看看