• Linux驱动模型之Kobjects、kset和ktype


    kobject到底是什么?

    它是驱动模型的骨架,从程序的角度来说,也可以理解为基类。通过sysfs文件系统为整体系统提供一个层级视图。
    Kobject对于内核的作用是什么?

    • 为容器保持一个引用计数器
    • 保持一个容器的链表或者合集
    • 为用户模式提供容器属性视图

    内核事件层:
    提供一个基于object的内核到用户层的通知系统,本质上它是通过netlink来实现的。

    相关数据结构

    include/linux/kobject.h:

    /* kernel object:对应sysfs文件系统中的一个目录:
     * 这个结构体一般不会单独的存在,一般会嵌入到其它的结构体中使用。
     */
    struct kobject {
    	const char		*name;		//显示的目录名字
    	struct list_head	entry;		//连接另外同属kset的kobject结构
    	struct kobject		*parent;		//父节点,用来实现层级视图
    	struct kset		*kset;		//指向kset合集
    	struct kobj_type	*ktype;		//提供kobject一族具有的普遍特性
    	struct kernfs_node	*sd; /* sysfs directory entry */
    	/* 引用计数,在注册当前的kobject或者向当前kobject注册子kobject时会增加引用计数
    	 * 添加属性时不会增加引用计数
    	 */
    	struct kref		kref;
    #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
    	struct delayed_work	release;
    #endif
    	unsigned int state_initialized:1;
    	unsigned int state_in_sysfs:1;		//kobject是否存在于sysfs中
    	unsigned int state_add_uevent_sent:1;
    	unsigned int state_remove_uevent_sent:1;
    	unsigned int uevent_suppress:1;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    设备驱动模型的核心数据结构是一个名叫kobject的普通数据结构,它会固定关联到sysfs文件系统:每个kobject在fs文件系统中都有一个相应的目录。Kobjects结构体会嵌入到一个用于描述设备驱动模型的元件中。比如buses, devices, and drivers(注意:这些结构体中都包含有kobject)。

    结构体成员说明:

    /* 引用计数,在注册当前的kobject或者向当前kobject注册子kobject时会增加引用计数
    添加属性时不会增加引用计数	 */
    struct kref		kref;		
    
    struct kset {
    	struct list_head list;	//组织相同类型的object的链表
    	spinlock_t list_lock;
    	struct kobject kobj;	//代表当前kset的内核kobject对象
    	const struct kset_uevent_ops *uevent_ops;	//核心功能:此kset的uevent操作
    } __randomize_layout;
    
    struct kset_uevent_ops {
    	int (* const filter)(struct kset *kset, struct kobject *kobj);	//需要过滤的事件
    	const char *(* const name)(struct kset *kset, struct kobject *kobj);
    	/* kset发送用户空间的事件 */
    	int (* const uevent)(struct kset *kset, struct kobject *kobj,
    		      struct kobj_uevent_env *env);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    从上面结构的成员来看,kset主要有两个作用:1.通过链表来组织相同类型的kbojet.2.通过kset_uevent_ops类提供kset集相关的uevnet操作。也即:维护相同类型的kobject,主要是在热插拔的时候通过kset_uevent_ops向用户空间发送事件。从而实现设备的动态加载和移除。

    struct kobj_type {
    	void (*release)(struct kobject *kobj);	//kobject对象释放回调函数
    	/* 和sysfs文件系统关联,来实现相关的操作.
    	 * 这个也是属性的读写操作必须要包含关联kobject的原因,
    	 * 因为只有这里提供和sysfs文件操作.
    	 */
    	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);
    };
    
    struct sysfs_ops {
    	ssize_t	(*show)(struct kobject *, struct attribute *, char *);
    	ssize_t	(*store)(struct kobject *, struct attribute *, const char *, size_t);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    从上面的数据结构可以看出kobject_type主要的几个功能:1.提供kobject对象释放函数。2.syfs文件系统的操作合集。3.体用默是的属性组。其中sys_ops提供show()和store()回调函数,作用跟它们的名字一样,起显示和保存的作用。

    结构体之间的关系

    kobject是整个文件系统的核心、基础,它类似于c++中的基类的作用。其中通过*parent的指针来构建了整个文件系统的视图。而在实际的使用中将它嵌入到其它的字符设备、平台设备等的结构,这样就将他们关联起来了。这种技巧在linux很多地方都有使用,比如container_of()。
    kset实际上就是很多类型相同的kobject的合集。
    kobj_type 对应不同的类型。
    下面这个图很好的展示了它们的关系:
    在这里插入图片描述

    kobject相关操作函数

    include/linux/kobject.h:
    extern void kobject_init(struct kobject *kobj, struct kobj_type *ktype);
    int kobject_add(struct kobject *kobj, struct kobject *parent,	const char *fmt, ...);
    int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, struct kobject *parent,
    const char *fmt, ...);
    void kobject_del(struct kobject *kobj);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    kset相关的操作函数

    #include 
    void kset_init(struct kset *k)
    int kset_register(struct kset *k)
    void kset_unregister(struct kset *k)
    static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
    static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    疑问

    kobject_init_and_add()中添加的buf_type和sysfs_create_file()的添加属性有什么区别和关系?
    通常来讲,由kobject相关的ktype所提供的默认属性是充足的。但是在一些特殊情况下会碰到特殊的kobject实例,它希望(甚至是必须)有自己的属性-也许是通用属性没包含那些需要的数据或者函数,为此,内核为能在默认之上,再添加新属性而提供了sysfs_create_file()接口。需要注意的是,kobject中ktype所对应的sysfs_ops操作将负责处理新属性。也就是是sysfs不会直接调用attribute提供的show()函数和store()函数,所以,ktype所对应的sysfs_ops操作需要实现处理新添加的attribute属性的功能。

  • 相关阅读:
    NAND价格第4季度回暖,现在是SSD入手时机吗?
    PyCharm 2022最新版详细图文安装教程(安装+运行测试+汉化+背景图设置)
    在 KubeSphere 中部署高可用 Redis 集群
    java实现PDF 转WORD
    基于单片机技术的自动停车器的设计
    JavaWeb——HTML(前端基础)
    [ Linux ] Linux信号概述 信号的产生
    gitee配置流水线实现自动打包vue
    关于model 需要定义 $fillable
    JSP通用材料收集归档系统eclipse定制开发mysql数据库BS模式java编程jdbc
  • 原文地址:https://blog.csdn.net/cqxcool66/article/details/126876454