• 设备模型的基础---kobject,kset


    设备模型的基础是kobject,kset,kobj_type。
    kobject本身并没有什么意义,真正有用的地方在于嵌入了kobject的结构体(对象),kobject可以看成是一个最小单元,sysfs的层次结构中的元素都是由kobject构成。

    kset与kobject的关系:
    kset会包含一类的kobject对象(内核链表串起来),而这些对象对应在sysfs中就是同一级的各个子目录,每一个kobject对象有自己的属性,这些属性就对应于各自子目录的文件。
    如此,就会构成一个有层次的组织结构。
    kset本身也包含一个kobject,但这个kobject与kset内核链表list中的kobjects并没有什么关系。

    kobject的两个主要作用:

    1.引用计数

    2.事件上报(kobject不加入某个kset是不会上报uevent的 http://www.cnblogs.com/black-mamba/p/5055683.html)

    相关文档:
    linux/Documentation/kobject.txt
    Documentation/filesystems/sysfs.txt
    Documentation/filesystems/sysfs-pci.txt

    linux/include/linux/kobject.h
    struct kset { 
    struct list_head list;//所有属于当前集合的kobject对象的链表
    spinlock_t list_lock; 
    struct kobject kobj; //与集合中包含的各个kobject无关,只是用来管理kset对象本身
    const struct kset_uevent_ops *uevent_ops;//用于将集合的状态信息传递给用户层。该机制有驱动程序的核心使用。
    };
    
    //描述内核对象的共同特性
    struct kobj_type { 
    void (*release)(struct kobject *kobj);
    const struct sysfs_ops *sysfs_ops;
    struct attribute **default_attrs;
    const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
    const void *(*namespace)(struct kobject *kobj);
    };
    
    //kobject直接嵌入到其他数据结构中,通过管理kobject即可以对包含kobject的对象进行管理。
    //kobject包含在一个层次化的组织中。
    struct kobject { 
    const char *name;//对象名称
    struct list_head entry;
    struct kobject *parent; //决定kobject出现在sysfs层次结构中的位置:如果存在父对象,那么需要在父对象对应的目录中新建一项;否则,将其放置到kobject所在的kset所属的kobject对应的目录中
    struct kset *kset;//集合指针
    struct kobj_type *ktype; 
    struct sysfs_dirent *sd;
    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;
    };
    
    struct kobj_attribute {
    struct attribute attr;
    ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,//用户空间读属性时,内核会调用该函数
    char *buf);
    ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,//用户空间写属性时,内核会调用该函数
    const char *buf, size_t count);
    };
    
    /disk/A9/linux-3.5/include/linux/sysfs.h
    struct attribute {
    const char *name;//显示的文件名
    umode_t mode;//文件的权限
    #ifdef CONFIG_DEBUG_LOCK_ALLOC
    bool ignore_lockdep:1;
    struct lock_class_key *key;
    struct lock_class_key skey;
    #endif
    };
    
    #define __ATTR(_name,_mode,_show,_store) {  
    .attr = {.name = __stringify(_name), .mode = _mode },  
    .show = _show,  
    .store = _store, 
    }
    
    struct attribute_group {
    const char *name;
    umode_t (*is_visible)(struct kobject *,
    struct attribute *, int);
    struct attribute **attrs;
    };
    
    struct kobject *kobject_get(struct kobject *kobj) //引用+1
    void kobject_put(struct kobject *kobj)//引用-1
    
    
    void kobject_init(struct kobject *kobj, struct kobj_type *ktype) 
    初始化kobeject结构体
    
    struct kobject *kobject_create(void)//非导出函数
    创建一个kobject结构体,并用kobject_init初始化
    
    int kobject_add(struct kobject *kobj, struct kobject *parent,
    const char *fmt, ...)
    注册一个kobject,在sysfs中生成相应的目录。
    如果parent为空,则kobject的parent指向其kset的kobject;如果kset也没有分配,则kobject位于/sys下
    
    struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
    创建一个kobject并注册到sysfs,失败返回空。
    
    int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, 
    struct kobject *parent, const char *fmt, ...) 
    初始化一个kobject并注册到sysfs,属性文件会自动生成。

    Q1:用户空间调用什么接口是与show、store是相对应的?

    linux/include/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.
    *
    * @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 {             
        struct list_head list;//所有属于当前集合的kobject对象的链表
        spinlock_t list_lock; 
        struct kobject kobj;  //与集合中包含的各个kobject无关,只是用来管理kset对象本身
        const struct kset_uevent_ops *uevent_ops;//用于将集合的状态信息传递给用户层。该机制由驱动程序的核心使用。
    }; 
    
    /**
     * kset_create - create a struct kset dynamically
     * 
     * @name: the name for the kset
     * @uevent_ops: a struct kset_uevent_ops for the kset
     * @parent_kobj: the parent kobject of this kset, if any.
     *                        
     * This function creates a kset structure dynamically.  This structure can
     * then be registered with the system and show up in sysfs with a call to
     * kset_register().  When you are finished with this structure, if
     * kset_register() has been called, call kset_unregister() and the
     * structure will be dynamically freed when it is no longer being used.
     * 
     * If the kset was not able to be created, NULL will be returned.
     */
     //非导出函数
    static struct kset *kset_create(const char *name, 
                    const struct kset_uevent_ops *uevent_ops,
                    struct kobject *parent_kobj) 
    /**
     * kset_init - initialize a kset for use
     * @k: kset
     */
    void kset_init(struct kset *k)
    
    /**
     * kset_register - initialize and add a kset.
     * @k: kset.
     */
    int kset_register(struct kset *k)
    
    /**
     * kset_unregister - remove a kset.
     * @k: kset.
     */
    void kset_unregister(struct kset *k)
    
    /**
     * kobject_uevent - notify userspace by sending an uevent
     *
     * @action: action that is happening
     * @kobj: struct kobject that the action is happening to
     *
     * Returns 0 if kobject_uevent() is completed with success or the
     * corresponding error when it fails.
     */
    int kobject_uevent(struct kobject *kobj, enum kobject_action action)
    
     
                    
    /**
     * kset_create_and_add - create a struct kset dynamically and add it to sysfs
     *
     * @name: the name for the kset
     * @uevent_ops: a struct kset_uevent_ops for the kset
     * @parent_kobj: the parent kobject of this kset, if any.
     *
     * This function creates a kset structure dynamically and registers it
     * with sysfs.  When you are finished with this structure, call
     * kset_unregister() and the structure will be dynamically freed when it
     * is no longer being used.
     *
     * If the kset was not able to be created, NULL will be returned.
     */
    struct kset *kset_create_and_add(const char *name,
                     const struct kset_uevent_ops *uevent_ops,
                     struct kobject *parent_kobj)
  • 相关阅读:
    2009年度最佳jQuery插件
    转:Jeff Dean的Stanford演讲
    Zookeeper的RPC框架
    转:电商推荐技术
    NoSQL设计思想(从辅到主)
    工作一年小结
    转:MySQL索引背后的数据结构
    java多线程并发,java的几种状态
    转发:Linux Socket编程
    几个linux shell的讲解网站
  • 原文地址:https://www.cnblogs.com/black-mamba/p/5055746.html
Copyright © 2020-2023  润新知