首页 > 代码库 > Linux内核系列设备模型(一) Kobject与Kset

Linux内核系列设备模型(一) Kobject与Kset

1、Kobject

Kobject是设备驱动模型的核心结构,它使所有设备在底层都有统一的接口。在内核注册的kobject对象都会对应sysfs文件系统中的一个目录(目录名称有Kobject结构中k_name指定)

struct kobject {
    const char        * k_name; // 指向设备名称的指针
    char            name[KOBJ_NAME_LEN]; // 设备名称
    struct kref        kref; //引用计数
    struct list_head    entry; //所属kset集合列表成员
    struct kobject        * parent; // 指向父节点对象
    struct kset        * kset; //所属kset集合
    struct kobj_type    * ktype; //设备类型
    struct dentry        * dentry; //与该对象对应的文件节点指针
    wait_queue_head_t    poll; //等待队列
};

相关操作函数:

extern void kobject_put(struct kobject *);

kobject引用计数减1(即kref减1),当kef的值为0时,将调用release函数释放该kobject对象;

struct kobject * kobject_get(struct kobject * kobj)

kobject引用计数增1;

extern int kobject_add(struct kobject *);

将kobject对象添加到所属的kset集合中,同时创建对应的文件目录(具体实现看kobject.c中的源码);
extern void kobject_del(struct kobject *);

删除kobject对象;

extern int kobject_register(struct kobject *);

注册kobject对象,先调用kobject_init进行初始化 ,然后调用kobject_add完成对象的注册,最后调用kobject_uevent注册kobject增加事件;

extern void kobject_unregister(struct kobject *);

注销kobject对象;先调用kobject_uevent注册KOBJ_REMOVE事件(事件通知作用),然后调用kobject_del删除对象,最后调用kobject_put减少该对象的引用计数,同样当引用计数为0时将会调用release销毁函数;

2、Kset

struct kset {
    struct subsystem    * subsys;  // 所属子系统
    struct kobj_type    * ktype; // 所属Kset集合的Kobject的类型
    struct list_head    list; // 所属Kset的Kobject对象链表头
    spinlock_t        list_lock; //Kset的互斥锁
    struct kobject        kobj; // 所属Kset的Kobject对象的父节点
    struct kset_uevent_ops    * uevent_ops; // Kset相关事件处理函数
};

相关操作函数:

static inline void kset_put(struct kset * k);

kset的引用计数减1,实际kset的引用计数使用的内嵌的Kobject对象的引用计数;

static inline struct kset * kset_get(struct kset * k)

kset的引用计数加1;

int kset_add(struct kset * k)

kset_add内部调用的是kobject_add,其实就是将kset的内嵌的kobject对象挂接到上层子系统中;

kset_register、kset_unregister与Kobject中对应操作函数实现比较类似(源码详情Kobject.c)

Kobject与Kset的关系图如下:

技术分享

3、Kobj_type

struct kobj_type {
    void (*release)(struct kobject *); //释放kobject函数
    struct sysfs_ops    * sysfs_ops; //属性操作字段(读和写)
    struct attribute    ** default_attrs; // 默认的属性字段,该字段指定的属性结构将以文件的形式输出到sysfs目录;

struct sysfs_ops {
    ssize_t    (*show)(struct kobject *, struct attribute *,char *buf); // 处理用户对属性值的读取,属性读取后的值保存在参数buf中;
    ssize_t    (*store)(struct kobject *,struct attribute *,const char *, size_t); // 处理用户设置的属性值
};

struct attribute {
    const char        * name; // 文件名
    struct module         * owner; // 所属模块
    mode_t            mode;
};

 

Linux内核系列设备模型(一) Kobject与Kset