02、注册 configfs 子系统实验
一、注册一个 configfs 子系统 实验
C
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/configfs.h>
//定义名为"myconfig_item_type"的配置项类型结构体
static const struct config_item_type myconfig_item_type ={
.ct_owner = THIS_MODULE,
.ct_item_ops = NULL,
.ct_group_ops = NULL,
.ct_attrs = 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 myconfigfs_init(void)
{
//初始化配置组
config_group_init(&myconfigfs_subsystem.su_group);
//注册子系统
configfs_register_subsystem(&myconfigfs_subsystem);
return 0;
}
// 模块退出函数
static void myconfigfs_exit(void)
{
configfs_unregister_subsystem(&myconfigfs_subsystem);
}
module_init(myconfigfs_init); // 指定模块的初始化函数
module_exit(myconfigfs_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
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
二、源码刨析
2.1、代码结构分析
头文件引入
plaintext
#include <linux/module.h> // 模块相关的基本功能
#include <linux/init.h> // 模块初始化和退出宏定义
#include <linux/slab.h> // 内核内存分配
#include <linux/configfs.h> // configfs框架支持
1
2
3
4
2
3
4
这些头文件提供了编写内核模块和configfs子系统所需的基本功能。
配置项类型定义
plaintext
static const struct config_item_type myconfig_item_type = {
.ct_owner = THIS_MODULE,
.ct_item_ops = NULL,
.ct_group_ops = NULL,
.ct_attrs = NULL,
};
1
2
3
4
5
6
2
3
4
5
6
这里定义了一个**config_item_type**
结构体实例:
**ct_owner**
: 指向当前模块- 其他字段都设为NULL,表示这个配置项没有定义操作函数或属性
配置子系统定义
plaintext
static struct configfs_subsystem myconfigfs_subsystem = {
.su_group = {
.cg_item = {
.ci_namebuf = "myconfigfs", // 子系统名称
.ci_type = &myconfig_item_type, // 关联的类型
},
},
};
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
定义了一个**configfs_subsystem**
结构体实例:
- 子系统名称为"myconfigfs"
- 关联之前定义的
**myconfig_item_type**
模块初始化函数
plaintext
static int myconfigfs_init(void)
{
config_group_init(&myconfigfs_subsystem.su_group); // 初始化配置组
configfs_register_subsystem(&myconfigfs_subsystem); // 注册子系统
return 0;
}
1
2
3
4
5
6
2
3
4
5
6
初始化流程:
- 调用
**config_group_init()**
初始化组结构 - 调用
**configfs_register_subsystem()**
向configfs注册这个子系统
模块退出函数
plaintext
static void myconfigfs_exit(void)
{
configfs_unregister_subsystem(&myconfigfs_subsystem); // 注销子系统
}
1
2
3
4
2
3
4
退出时注销之前注册的子系统。
模块声明
plaintext
module_init(myconfigfs_init); // 指定初始化函数
module_exit(myconfigfs_exit); // 指定退出函数
MODULE_LICENSE("GPL"); // 声明模块使用GPL许可证
1
2
3
2
3
这些宏定义了模块的入口、出口和许可证信息。
2.2、整体工作流程
模块加载时:
- 内核调用
**myconfigfs_init()**
函数 - 初始化配置组结构
- 向configfs注册名为"myconfigfs"的子系统
- 在/sys/config/下会创建一个名为"myconfigfs"的目录
- 内核调用
模块存在期间:
- 用户可以通过/sys/config/myconfigfs/目录与子系统交互
- 由于没有定义属性和操作函数,这个子系统实际上不提供任何可配置项
模块卸载时:
- 内核调用
**myconfigfs_exit()**
函数 - 从configfs注销子系统
- /sys/config/myconfigfs/目录被移除
- 内核调用
2.3、功能说明
这段代码实现了一个非常基础的configfs子系统框架,实际上它只是创建了一个空壳,因为:
- 没有定义任何属性(
**ct_attrs**
为NULL) - 没有定义任何操作函数(
**ct_item_ops**
和**ct_group_ops**
为NULL)
在实际应用中,开发者通常会:
- 定义自己的属性和操作函数
- 实现更复杂的配置项层次结构
- 添加业务逻辑处理配置变更
这个示例只是展示了configfs子系统的最基本结构,可以作为更复杂实现的起点。