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;
};

设备驱动模型的核心数据结构是一个名叫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);
};

从上面结构的成员来看,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);
};

从上面的数据结构可以看出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);

kset相关的操作函数

#include <linux/kobject.h>
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)

疑问

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属性的功能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值