KOBJ虚拟文件系统 (kobj)
本文档详细介绍 XSTAR 的 KOBJ(Kernel Object)虚拟文件系统,包括数据结构、API 接口和使用示例。
目录
引言
KOBJ 的作用
KOBJ(Kernel Object)即内核对象,其层次结构表现为一棵倒置的树,用来管理各种设备、驱动、运行时状态等。
在文件系统中,通过 sysfs 接口绑定 kobj 节点,来实现对该节点的读写操作。sysfs 接口有两种基本用途:
- 组件外部操作接口:应用可以通过此接口操作设备
- 调试驱动模块或查看运行时状态:通过读写 kobj 节点获取设备信息
核心价值
实现 kobj 可以对任何形态的组件进行高度抽象,是各种组件的基石。系统提供了一组 API,以方便管理 kobj。
理解了 kobj,对理解 XSTAR 中的各种核心组件(如设备驱动、设备管理等)有相当大的帮助,建议细心阅读。
KOBJ 节点类型
kobj 有两种基本类型:
目录类型(KOBJ_TYPE_DIR)
- 可以挂接子节点
- 类似文件系统中的目录
- 不提供读写接口
- 用于组织节点层次结构
文件类型(KOBJ_TYPE_REG)
- 代表树的末端节点
- 不可拥有子节点
- 提供读或写接口
- 用于存储和传递数据
枚举定义:
enum kobj_type_t {
KOBJ_TYPE_DIR,
KOBJ_TYPE_REG,
};
KOBJ 结构体
kobj_t 结构 定义
kobj 结构体拥有名字、节点类型、父节点指针、当前节点链表、子节点链表头、读写接口函数及一个私有数据指针。
struct kobj_t {
char * name; /* kobj 名称 */
enum kobj_type_t type; /* kobj 类型 DIR 或 REG */
struct kobj_t * parent; /* kobj 的父节点 */
struct list_head_t entry; /* kobj 的链表项 */
struct list_head_t children; /* kobj 的子节点链表 */
ssize_t (*read)(struct kobj_t * kobj, void * buf, size_t size); /* 读接口 */
ssize_t (*write)(struct kobj_t * kobj, void * buf, size_t size); /* 写接口 */
void * priv; /* 私有数据 */
};
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
name | char * | 节点名称,必须唯一(同一父节点下) |
type | enum kobj_type_t | 节点类型:目录或文件 |
parent | struct kobj_t * | 父节点指针 |
entry | struct list_head_t | 链表项,用于挂载到父节点的 children 链 表 |
children | struct list_head_t | 子节点链表头 |
read | 函数指针 | 读操作回调函数(仅文件类型有效) |
write | 函数指针 | 写操作回调函数(仅文件类型有效) |
priv | void * | 私有数据,可存储任意用户数据 |
回调函数类型
typedef ssize_t (*kobj_read_t)(struct kobj_t * kobj, void * buf, size_t size);
typedef ssize_t (*kobj_write_t)(struct kobj_t * kobj, void * buf, size_t size);
回调函数参数:
kobj:kobj 节点指针buf:缓冲区指针size:缓冲区大小
回调函数返回值:
- 成功:返回实际读写的字节数
- 失败:返回负值
KOBJ API
获取根节点
获取 kobj 根节点,如果不存在则自动创建。
函数原型:
struct kobj_t * kobj_get_root(void);
返回值:
- 成功:返回根节点指针
- 失败:返回 NULL
说明:
- 根节点名称为 "kobj"
- 根节点为全局静态变量
- 根节点也是 sysfs 的顶层目录节点
- 在 mount 文件系统时会挂载到
/sys目录
搜索节点
从父节点中搜索名为 name 的子节点。
函数原型:
struct kobj_t * kobj_search(struct kobj_t * parent, const char * name);
参数:
parent:父节点指针name:要搜索的节点名称
返回值:
- 找到:返回节点指针
- 未找到:返回 NULL
使用示例:
struct kobj_t *root = kobj_get_root();
struct kobj_t *device = kobj_search(root, "device");
搜索或创建目录
从父节点中搜索名为 name 的子节点,如果不存在则创建一个目录节点。
函数原型:
struct kobj_t * kobj_search_directory_with_create(struct kobj_t * parent, const char * name);
参数:
parent:父节点指针name:目录名称
返回值:
- 成功:返回目录节点指针
- 失败:返回 NULL
说明:
- 如果节点不存在,自动创建一个目录节点
- 如果节点存在但不是目录类型,返回 NULL
- 常用于确保路径上的目录节点存在
使用示例:
struct kobj_t *root = kobj_get_root();
struct kobj_t *device = kobj_search_directory_with_create(root, "device");
struct kobj_t *gpio = kobj_search_directory_with_create(device, "gpio");
分配目录节点
分配一个目录类型的 kobj 节点。
函数原型:
struct kobj_t * kobj_alloc_directory(const char * name);
参数:
name:目录名称
返回值:
- 成功:返回分配的目录节点指针
- 失败:返回 NULL
说明:
- 仅分配内存并初始化,不添加到父节点
- 需要调用
kobj_add添加到父节点 - 目录节点不提供读写接口
使用示例:
struct kobj_t *dir = kobj_alloc_directory("my-directory");
if(dir) {
kobj_add(parent, dir);
}