zoukankan      html  css  js  c++  java
  • Linux设备管理(一):kobject, kset, ktype分析

    /************************************************************************************

    本文为个人学习记录,如有错误,欢迎指正。

    本文参考资料: 

    *        https://blog.csdn.net/yyplc/article/details/7465569

    *        https://www.cnblogs.com/xiaojiang1025/p/6193959.html

    *        https://www.cnblogs.com/helloahui/p/3677192.html

    *        https://www.cnblogs.com/helloahui/p/3674933.html

    ************************************************************************************/

    1. kobject

    kobject是Linux 2.6后引入的新的设备管理机制,在内核中由struct kobject表示。通过这个数据结构使所有设备在底层都具有统一的接口,kobject提供基本的对象管理,是构成Linux2.6设备模型的核心结构。它与sysfs文件系统紧密关联,每个在内核中注册的kobject对象都对应于sysfs文件系统中的一个目录。

    kobject是组成设备模型的基本结构。类似于C++中的基类,它嵌入于更大的对象的对象中--所谓的容器--用来描述设备模型的组件。如bus,devices, drivers 都是典型的容器。这些容器就是通kobject连接起来了,形成了一个树状结构,这个树状结构就与/sys相对应。

    kobject 结构为一些大的数据结构和子系统提供了基本的对象管理,避免了类似机能的重复实现。这些机能包括
    (1) 对象引用计数;
    (2)维护对象链表(集合);
    (3)对象上锁;
    (4)在用户空间的表示。

    struct kobject 
    {
    const char *name; //表示kobject对象的名字,对应sysfs下的一个目录 struct list_head entry; //是kobject中插入的head_list结构 struct kobject *parent; //指向当前kobject父对象的指针,体现在sys结构中就是包含当前kobject对象的目录对象 struct kset *kset; //表示当前kobject对象所属的集合 struct kobj_type *ktype; //表示当前kobject的类型,包含了kobject相关的操作函数和属性 struct sysfs_dirent *sd;          //用于表示VFS文件系统的目录项,是设备与文件之间的桥梁,sysfs中的符号链接就是通过kernfs_node内的联合体实现的 struct kref kref; //对kobject的引用计数,当引用计数为0时,就回调之前注册的release方法释放该对象 unsigned int state_initialized:1; //初始化标志位,在对象初始化时被置位,表示对象是否已经被初始化 unsigned int state_in_sysfs:1; //表示kobject对象在sysfs中的状态,在对应目录中被创建则置1,否则为0 unsigned int state_add_uevent_sent:1; //添加设备的uevent事件是否发送标志,添加设备时会向用户空间发送uevent事件,请求新增设备 unsigned int state_remove_uevent_sent:1; //删除设备的uevent事件是否发送标志,删除设备时会向用户空间发送uevent事件,请求卸载设备 unsigned int uevent_suppress:1; };

    Linux内核中提供以下操作kobject的函数。

    //kobject初始化函数
    void kobject_init(struct kobject * kobj);
    
    //设置指定kobject的名称
    int kobject_set_name(struct kobject *kobj, const char *format, ...);
    
    //将kobj对象的引用计数加1,同时返回该对象的指针
    struct kobject *kobject_get(struct kobject *kobj);
    
    //将kobj对象的引用计数减1,如果引用计数降为0,则调用kobject release()释放该kobject对象
    void kobject_put(struct kobject * kobj); 
    
    //将kobj对象加入Linux设备层次。挂接该kobject对象到kset的list链中,增加父目录各级kobject的引用计数,在其 parent指向的目录下创建文件节点,并启动该类型内核对象的hotplug函数
    int kobject_add(struct kobject * kobj);
    
    //kobject注册函数。通过调用kobject init()初始化kobj,再调用kobject_add()完成该内核对象的注册
    int kobject_register(struct kobject * kobj);
    
    //从Linux设备层次(hierarchy)中删除kobj对象
    void kobject_del(struct kobject * kobj);
    
    //kobject注销函数。与kobject register()相反,它首先调用kobject del从设备层次中删除该对象,再调用kobject put()减少该对象的引用计数,如果引用计数降为0,则释放kobject对象
    void kobject_unregister(struct kobject * kobj);

    2. ktype

    ktype表示当前kobject的类型,其中包含了kobject相关的操作函数和属性。

    struct kobj_type 
    {
        void (*release)(struct kobject *kobj); //release方法用于释放kobject占用的资源
        const struct sysfs_ops *sysfs_ops;     //指向sysfs操作表
        struct attribute **default_attrs;      //sysfs文件系统缺省列表属性
        const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
        const void *(*namespace)(struct kobject *kobj);
    };

    sysfs操作表包括两个函数store()和show()。当用户态读取属性 时,show()函数被调用,该函数编码指定属性值存入buffer中返回给用户态;而store()函数用于存储用户态传入的属性值。详见Linux设备管理:sysfs文件系统的功能及其应用

    struct sysfs_ops 
    {
        ssize_t    (*show)(struct kobject *, struct attribute *,char *);
        ssize_t    (*store)(struct kobject *,struct attribute *,const char *, size_t);
    };

    attribute, 属性。它以文件的形式输出到sysfs的目录当中,在kobject对应的目录下面。文件名为name。文件读写的方法对应于kobj type中的sysfs ops。

    struct attribute 
    {
        const char        *name;
        struct module     *owner;
        mode_t             mode;
    };

    3. kset

    kset最重要的是建立上层(sub-system)和下层的(kobject)的关联性。

    kset表示一组kobject的集合,kobject通过kset组织成层次化的结构,所有属于该kset的kobjetc结构的parent指针指向kset包含的kobject对象,构成一个父子层次关系。这些kobject可以是不同或相同的类型(kobj_type)。sysfs中的设备组织结构很大程度上都是根据kset进行组织的,比如"/sys/drivers"目录就是一个kset对象,包含系统中的驱动程序对应的目录,驱动程序的目录又由kobject表示。比如在平台设备模型中,当我们注册一个设备或驱动到平台总线,其实是将对应的kobject挂接到platform总线的kset上,每种总线都是维护两条链表(两个kset),一条用于链接挂接在上面的驱动(驱动kset),一条用于链接挂接在上面的设备(设备kset)。

    struct kset 
    {
        struct list_head list;
        spinlock_t list_lock;
        struct kobject kobj;
        const struct kset_uevent_ops *uevent_ops;
    };

    图片引用于网络

    5. kobject、ktype、kset之间的联系

    kobject、ktype、kset之间的联系如下图所示。。

  • 相关阅读:
    leetcode 1. 两数之和
    leetcode 671. 二叉树中第二小的节点
    leetcode 100. 相同的树
    leetcode 110. 平衡二叉树
    leetcode 144. 二叉树的前序遍历
    1066. Root of AVL Tree (25)
    leetcode 100 相同的树
    leeCode 515 在每个树行中找最大值
    LeetCode 31.下一个排列
    面向对象UML中类关系
  • 原文地址:https://www.cnblogs.com/linfeng-learning/p/9306289.html
Copyright © 2011-2022 走看看