本章节是一个在 Linux 系统上创建 kset 的实验。实验展示了如何通过编写代码创建 kset,并将多个 kobject 对象关联到这个集合中。通过实验现象可以看到,kset 其实就是多个 kobject 的容器,而每个 kobject 都会在 /sys 目录下自动生成对应的文件节点,这就是它们出现在该目录的原因。
一、kset 与 kobject 的关系
kset 与 kobject 的关系图:

二、kset 编程接口
- 创建一个 kset 对象
- 指定 kset 的 parent
- 创建 kset 下的属性
c
void kset_init (struct kset *kset);
int kset_register (struct kset *kset);
void kset_unregister (struct kset *kset);
struct kset *kset_create_and_add (const char *name,
const struct kset_uevent_ops *u,
struct kobject *parent_kobj);1
2
3
4
5
6
2
3
4
5
6
三、实验
源代码下载
bash
git clone git@gitee.com:yangxuesong314/linux-driver.git1
- 若之前已 git 拉取代码可以忽略
- 代码位于:
linux-driver/02.Linux设备模型/03.创建kset实验
这段代码用于定义并初始化两个自定义内核对象 mykobject01 和 mykobject02,并将它们添加到一个自定义内核对象集合 mykset 中。这些自定义内核对象可以用于在 Linux 内核中表示和管理特定的功能或资源。
c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/configfs.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
// 定义 kobject 结构体指针,用于表示第一个自定义内核对象
struct kobject *mykobject01;
// 定义 kobject 结构体指针,用于表示第二个自定义内核对象
struct kobject *mykobject02;
// 定义 kset 结构体指针,用于表示自定义内核对象的集合
struct kset *mykset;
// 定义 kobj_type 结构体,用于定义自定义内核对象的类型
struct kobj_type mytype;
// 模块的初始化函数
static int mykobj_init(void)
{
int ret;
// 创建并添加 kset,名称为 "mykset",父 kobject 为 NULL,属性为 NULL
mykset = kset_create_and_add("mykset", NULL, NULL);
// 为 mykobject01 分配内存空间,大小为 struct kobject 的大小,标志为 GFP_KERNEL
mykobject01 = kzalloc(sizeof(struct kobject), GFP_KERNEL);
// 将 mykset 设置为 mykobject01 的 kset 属性
mykobject01->kset = mykset;
// 初始化并添加 mykobject01,类型为 mytype,父 kobject 为 NULL,格式化字符串为 "mykobject01"
ret = kobject_init_and_add(mykobject01, &mytype, NULL, "%s", "mykobject01");
// 为 mykobject02 分配内存空间,大小为 struct kobject 的大小,标志为 GFP_KERNEL
mykobject02 = kzalloc(sizeof(struct kobject), GFP_KERNEL);
// 将 mykset 设置为 mykobject02 的 kset 属性
mykobject02->kset = mykset;
// 初始化并添加 mykobject02,类型为 mytype,父 kobject 为 NULL,格式化字符串为 "mykobject02"
ret = kobject_init_and_add(mykobject02, &mytype, NULL, "%s", "mykobject02");
return 0;
}
// 模块退出函数
static void mykobj_exit(void)
{
// 释放 mykobject01 的引用计数
kobject_put(mykobject01);
// 释放 mykobject02 的引用计数
kobject_put(mykobject02);
}
module_init(mykobj_init); // 指定模块的初始化函数
module_exit(mykobj_exit); // 指定模块的退出函数
MODULE_LICENSE("GPL"); // 模块使用的许可证1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
驱动加载 insmod make_kset.ko 之后,我们进入 /sys/ 目录下,可以看到创建生成的 mykset:
