我是靠谱客的博主 儒雅飞机,这篇文章主要介绍设备驱动模型之:kobject,kset,ktype(四),现在分享给大家,希望可以做个参考。

之前的博客介绍的关于kobject的一些操作和函数的用法,此篇博客介绍关于kset函数的一些操作,顺便把有关于kset的kobject函数的一些用法补齐,这样才会有知识共享的效果;
关于kset的操作的函数以及操作的作用有以下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1. extern void kset_init(struct kset *kset); 关于kset初始化的操作,主要初始化如下: (1)初始化kobject的kref,entry,state_initialized (2) 初始化kset自旋锁,初始化kset的链表 2.extern int __must_check kset_register(struct kset *kset); kset函数组册进入内核,在kset函数注册进入内核过程中,会先执行kset_init操作,然后添加kset->kobj的/sys/下的文件夹,最后执行kset_uevent函数,此函数主要是执行根kset下的uevent_ops; 什么是根kset下的uevent_ops? 在内核中使用如下: while (!top_kobj->kset && top_kobj->parent) top_kobj = top_kobj->parent; 可以看到是最后一个kset->kob的parent的kset不为空的情况下的uevent_ops; 注意: 在kset注册进入内核过程中,需要将kset->kobj->name赋予值,如果需要则需要将kset->kobj->kset赋予值,如果需要则将kset->uevent_ops赋予值;其中将kset->kobj->name赋予值是必须的操作; 3.extern void kset_unregister(struct kset *kset); 将kset注销出内核,前提是kset->kobj->kref计数为0; 4.extern struct kset * __must_check kset_create_and_add(const char *name, const struct kset_uevent_ops *u, struct kobject *parent_kobj); 此操作是申请一段内存并且初始化,把kset->kobj->name赋予name,将kset->uevent_ops赋予u,并且将kset->kobj->parent赋予parent_kobj; 总体和kset_register是一致的,更加简化了而已;

下面是对于kset_init/kset_register/kset_unregister/kset_create_and_register的详细解释;
kset_init函数接口:

复制代码
1
2
3
4
5
6
7
8
函数原型: extern void kset_init(struct kset *kset); 函数参数: struct kset* kset,要初始化的kset实例; 函数作用: 初始化kset->kobject实例,主要初始化kset->kobj->entry/state_initialized/kref; 初始化kset->list/list_lock操作;

kset_init函数:

复制代码
1
2
3
4
5
6
7
void kset_init(struct kset *k) { kobject_init_internal(&k->kobj); INIT_LIST_HEAD(&k->list); spin_lock_init(&k->list_lock); }

kset_register函数接口:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
函数原型: int kset_register(struct kset *k) 函数参数: struct kset*k;要注册进入内核的kset结构体指针实例; 函数作用: 1.向内核注册kset->kobj实例,主要调用kobject_init_internel函数向内核注册进入kset->kobj; 2.调用kset_uevent使用父kset的uevent_ops; 使用注意事项: 1.使用kset_register时候主要是在没有使用kset_init时候,但是这时候kset->kobj->name还没有设置,需要在使用此函数之前设置; 2.使用kset_register时候如果此kset还包括在另外一个kset下,在此函数之前需要手动设置kset->kobj->kset指针; 3.使用kset_register时候如果本kset有自己的ktype则需要手动设置,并且初始化;

kset_register函数:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int kset_register(struct kset *k) { int err; if (!k) return -EINVAL; kset_init(k); err = kobject_add_internal(&k->kobj);//向内核中增加kobj if (err) return err; kobject_uevent(&k->kobj, KOBJ_ADD);//使用kset->uevent_ops; return 0; }

kset_unregister函数:

复制代码
1
2
3
4
5
6
7
函数原型: void kset_unregister(struct kset *k) 函数参数: struct kset*k要向内核中注销的kset; 函数作用: 通过调用kobj_put(kset->obj),使kset引用计数减一,如果减少到0,则调用kset->kobj->ktype->release对于kset释放操作(如果有定义的话);
复制代码
1
2
3
4
5
6
7
void kset_unregister(struct kset *k) { if (!k) return; kobject_put(&k->kobj); }

kset_create_and_add函数:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
函数原型: struct kset *kset_create_and_add(const char *name, const struct kset_uevent_ops *uevent_ops, struct kobject *parent_kobj) 函数参数: const char * name要创建的kset->kobj的名字; const struct kset_uevent_ops * uevent_ops; kset->uevent_ops指针指向的地方; stuct kobject * parent_kobj; kset->kobj->parent指向的父kobject; 函数作用: 1.通过kmalloc申请一段kset,并且初始化,把kset->kobj->parent指向parent_kobj, 把kset->uevent_ops指向uevent_ops,把name赋予kset->kobj->name指针; 2.把默认的kset->kobj->ktype指针赋予全局的kset_type指针,注意:在此之后不能随意更改kset->kobj->ktype,否则,会出现一系列的操作性问题; 3.调用kset_register向内核注册;

kset_create_and_add

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct kset *kset_create_and_add(const char *name, const struct kset_uevent_ops *uevent_ops, struct kobject *parent_kobj) { struct kset *kset; int error; /***向内核申请内存并且初始化kset,赋予相应的指针**/ kset = kset_create(name, uevent_ops, parent_kobj); if (!kset) return NULL; error = kset_register(kset);//向内核注册进入kset; if (error) { kfree(kset); return NULL; } return kset; }

最后

以上就是儒雅飞机最近收集整理的关于设备驱动模型之:kobject,kset,ktype(四)的全部内容,更多相关设备驱动模型之:kobject内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(118)

评论列表共有 0 条评论

立即
投稿
返回
顶部