05、注册 attribute 实验
一、注册 attribute 实验
C
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/configfs.h>
// 定义一个名为"mygroup"的config_group结构体
static struct config_group mygroup;
// 自定义的配置项结构体
struct myitem
{
struct config_item item;
int size;
void *addr;
};
// 配置项释放函数
void myitem_release(struct config_item *item)
{
struct myitem *myitem = container_of(item, struct myitem, item);
kfree(myitem);
printk("%s\n", __func__);
};
// 读取配置项内容的回调函数
ssize_t myread_show(struct config_item *item, char *page)
{
struct myitem *myitem = container_of(item, struct myitem, item);
memcpy(page, myitem->addr, myitem->size);
printk("%s\n", __func__);
return myitem->size;
};
// 写入配置项内容的回调函数
ssize_t mywrite_store(struct config_item *item, const char *page, size_t size)
{
struct myitem *myitem = container_of(item, struct myitem, item);
myitem->addr = kmemdup(page, size, GFP_KERNEL);
myitem->size = size;
printk("%s\n", __func__);
return myitem->size;
};
// 创建只读配置项
CONFIGFS_ATTR_RO(my, read);
// 创建只写配置项
CONFIGFS_ATTR_WO(my, write);
// 配置项属性数组
struct configfs_attribute *my_attrs[] = {
&myattr_read,
&myattr_write,
NULL,
};
// 配置项操作结构体
struct configfs_item_operations myitem_ops = {
.release = myitem_release,
};
// 配置项类型结构体
static struct config_item_type mygroup_item_type = {
.ct_owner = THIS_MODULE,
.ct_item_ops = &myitem_ops,
.ct_attrs = my_attrs,
};
// 创建配置项函数
struct config_item *mygroup_make_item(struct config_group *group, const char *name)
{
struct myitem *myconfig_item;
printk("%s\n", __func__);
myconfig_item = kzalloc(sizeof(*myconfig_item), GFP_KERNEL);
config_item_init_type_name(&myconfig_item->item, name, &mygroup_item_type);
return &myconfig_item->item;
}
// 删除配置项函数
void mygroup_delete_item(struct config_group *group, struct config_item *item)
{
struct myitem *myitem = container_of(item, struct myitem, item);
config_item_put(&myitem->item);
printk("%s\n", __func__);
}
// 配置组操作结构体
struct configfs_group_operations mygroup_ops = {
.make_item = mygroup_make_item,
.drop_item = mygroup_delete_item,
};
// 配置项类型结构体
static const struct config_item_type mygroup_config_item_type = {
.ct_owner = THIS_MODULE,
.ct_group_ops = &mygroup_ops,
};
// 配置项类型结构体
static const struct config_item_type myconfig_item_type = {
.ct_owner = THIS_MODULE,
.ct_group_ops = NULL,
};
// 定义一个configfs_subsystem结构体实例"myconfigfs_subsystem"
static struct configfs_subsystem myconfigfs_subsystem = {
.su_group = {
.cg_item = {
.ci_namebuf = "myconfigfs",
.ci_type = &myconfig_item_type,
},
},
};
// 模块的初始化函数
static int myconfig_group_init(void)
{
// 初始化配置组
config_group_init(&myconfigfs_subsystem.su_group);
// 注册子系统
configfs_register_subsystem(&myconfigfs_subsystem);
// 初始化配置组"mygroup"
config_group_init_type_name(&mygroup, "mygroup", &mygroup_config_item_type);
// 在子系统中注册配置组"mygroup"
configfs_register_group(&myconfigfs_subsystem.su_group, &mygroup);
return 0;
}
// 模块退出函数
static void myconfig_group_exit(void)
{
// 注销子系统
configfs_unregister_subsystem(&myconfigfs_subsystem);
}
module_init(myconfig_group_init); // 指定模块的初始化函数
module_exit(myconfig_group_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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
二、源码刨析
- 创建配置项:
plaintext
mkdir /config/myconfigfs/mygroup/test
1
- 触发
mygroup_make_item()
- 分配新的
myitem
结构体 - 写入数据:
plaintext
echo "hello" > /config/myconfigfs/mygroup/test/write
1
- 触发
mywrite_store()
- 分配内存并保存数据
- 读取数据:
plaintext
cat /config/myconfigfs/mygroup/test/read
1
- 触发
myread_show()
- 返回存储的数据
- 删除配置项:
plaintext
rmdir /config/myconfigfs/mygroup/test
1
- 触发
mygroup_delete_item()
- 最终调用
myitem_release()