驱动-设备树插件注册子系统
设备数插件注册子系统简单案例
文章目录
- 前言
- 参考资料
- 一、操作实验
- 实验代码
- 实测结果
- 代码分析
- ConfigFS 重要结构体重温
- 顶层子系统- configfs_subsystem
- 二、API说明
- 函数:config_group_init
- 函数:config_group_init
- 总结
前言
前面了解了设备树插件语法,设备树插件基础知识,特别是在基础知识中或者其它设备树插件入门篇中 了解了ConfigFS体系基础知识和ConfigFS 结构体。 那么 接下来就是需要一步一步根据结构体实现业务流程,最终实现内核配置编程。
这里仅从顶层子系统 案例来了解、学习 子系统注册知识点。
参考资料
设备树插件基础必备
注册configfs子系统实验
linux之configfs简介和编程入门
configfs-用户空间控制的内核对象配置
一、操作实验
实验代码
代码如下,流程再简单不过了:
- 定义了 configfs_subsystem 结构体和它的su_group,以及su_group 下的cg_item,cg_item 下的 ci_namebuf 、ci_type
- 定义了 config_item_type 结构体内容,属性和子节点为NULL
#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"); // 模块使用的许可证
MODULE_AUTHOR("wfc"); // 模块的作者
实测结果
编译好驱动文件 insmod configfs_subsystem.ko
,加载后:/sys/kernel/config 目录下
查看目录
代码分析
ConfigFS 重要结构体重温
为什么要重温这几个重要的结构体,放在这里方便对比看看。 比如你看 su_group、cg_item、ci_namebuf、ci_type
为什么在定义configfs_subsystem
结构体时候,属性需要那样写 写这些值? 为什么? 因为人家结构体里面就是这样定义的,那么固定属性值就是这些。 那么 就需要你自己见名知意了。
重要几个在结构体数据如下:
// 子系统
struct configfs_subsystem {struct config_group su_group;struct mutex su_mutex;
};/*** group - a group of config_items of a specific type, belonging* to a specific subsystem.*/
struct config_group {struct config_item cg_item;struct list_head cg_children;struct configfs_subsystem *cg_subsys;struct list_head default_groups;struct list_head group_entry;
};struct config_item {char *ci_name;char ci_namebuf[CONFIGFS_ITEM_NAME_LEN];struct kref ci_kref;struct list_head ci_entry;struct config_item *ci_parent;struct config_group *ci_group;const struct config_item_type *ci_type;struct dentry *ci_dentry;
};struct config_item_type {struct module *ct_owner;struct configfs_item_operations *ct_item_ops;struct configfs_group_operations *ct_group_ops;struct configfs_attribute **ct_attrs;struct configfs_bin_attribute **ct_bin_attrs;
};
顶层子系统- configfs_subsystem
为什么要重温这几个重要的结构体,放在这里方便对比看看。 那是因为 你看下面的顶层子系统定义,如下:
你看` su_group、cg_item、ci_namebuf、ci_type````java
// 定义一个configfs_subsystem结构体实例"myconfigfs_subsystem"
static struct configfs_subsystem myconfigfs_subsystem = {.su_group = {.cg_item = {.ci_namebuf = "myconfigfs",.ci_type = &myconfig_item_type,}}};
就这一个顶层configfs_subsystem 结构体的定义,其实就定义了好几方面内容:
- 定义了子系统configfs_subsystem 是myconfigfs_subsystem
- 定义了config_group 是 su_group
- 定义了config_item 是cg_item
- 定义了 ci_name 属性值是 myconfigfs,代表顶层结构值名称是 myconfigfs
- 定义了config_item_type 指向ci_type,就是 myconfig_item_type 指针
对于 config_item_type 结构体如下、同时代码中myconfig_item_type 定义实则样的? 如下
struct config_item_type {struct module *ct_owner;struct configfs_item_operations *ct_item_ops;struct configfs_group_operations *ct_group_ops;struct configfs_attribute **ct_attrs;struct configfs_bin_attribute **ct_bin_attrs;
};```java
// 定义名为"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,
};
二、API说明
函数:config_group_init
config_group_init 是 Linux 内核中 ConfigFS 子系统的一个函数,用于初始化一个 config_group 结构体。
功能
- 初始化 config_group 结构体的基本字段
- 设置默认的 group 操作(如果未提供)
- 准备 group 以便后续注册到 ConfigFS 中
函数:config_group_init
configfs_register_subsystem 是用于向 ConfigFS 注册一个子系统的函数。
功能
- 将一个新的子系统注册到 ConfigFS 文件系统中
- 在 configfs 挂载点下创建对应的目录结构
- 使子系统的配置接口对用户空间可见
总结
- 实际简单案例说明顶层子系统的注册 演示
- 子系统注册演示,最终结果在
/sys/kernel/config
路径下看到我们注册的子系统 - 简单demo 演示,理解子系统。重温ConfigFS 重要结构体。理解为什么属性名就是那些。