Linux configfs简介

  1.        基本概念

         了解Linux configfs优先阅读kernel中configfs的文档,(https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt)。

        文档中介绍configfs是基于ram的文件系统,这一点与sysfs很像,但是与sysfs不同之处在于,configfs可以通过在用户态的操作创建和删除内核对象,而我们一般使用sysfs是已经有内核对象之后,再去创建sysfs文件节点。从使用上看都可以通过read write读取/修改文件属性,重点在于sysfs的内核对象是在内核创建、销毁的,sysfs是访问这些内核对象的窗口。但是configfs的内核对象的创建/销毁是由用户态的mkdir等操作完成,用户执行mkdir会在内核创建一个config_item对象,用户执行rmdir会销毁这个对象。

        这确实是一个很天才的想法,尤其适合动态修改配置以加载不同驱动的场景。例如,早期的USB只支持单一的gadget设备,使用场景较为简单,随后加入了composite framework,用来支持多个function的gadget设备,多个function的绑定在内核中完成,若需要修改,则需要修改内核,不灵活也不方便。Linux3.11版本引入了基于configfs的usb gadget configfs。usb gadget configfs重新实现了复合设备层,使用者可以在用户空间配置和组合内核的function,灵活的构成USB复合设备,极大了提高了工作效率。

2. 使用configfs

        configfs可以被编译成模块或者直接编译进内核,通过mount -t configfs none /sys/kernel/config/可以使用configfs

        configfs支持注册subsystem,官网介绍如下:

通过configfs_register_subsystem()configfs_subsystem给注册进去,注册完之后,相关的config_group就是可见的了,并且需要支持mkdir操作。usb gadget_subsys子系统的注册过程如下

static int __init gadget_cfs_init(void)
{
	int ret;

	config_group_init(&gadget_subsys.su_group);

	ret = configfs_register_subsystem(&gadget_subsys);
	return ret;
}
module_init(gadget_cfs_init);

3. configfs数据结构

        我们按照从顶往下的顺序来看,首先是subsystem,它是configfs的最顶层,比如:/sys/kernel/config/usb_gadget、/sys/kernel/config/iio

struct configfs_subsystem {
	struct config_group	su_group;    //config_subsystem是一类config_group
	struct mutex		su_mutex;
};

从configfs_subsystem数据结构中发现了config_group数据结构:

/**
 *	group - a group of config_items of a specific type, belonging
 *	to a specific subsystem.
 */
struct config_group {
	struct config_item		cg_item;        //config_group是一类config_item
	struct list_head		cg_children;
	struct configfs_subsystem 	*cg_subsys;
	struct list_head		default_groups;
	struct list_head		group_entry;
};

从config_group数据结构的注释中,我们知道config_group是一组config_items的组合,我们再看

config_item数据结构,如下:

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;
};

在config_item中有config_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;    //目录下的文件
};

从用户的角度看,一个文件系统下有目录和文件两种对象,configfs_attribute和configfs_bin_attribute对应文件

struct configfs_attribute {
	const char		*ca_name;
	struct module 		*ca_owner;
	umode_t			ca_mode;
	ssize_t (*show)(struct config_item *, char *);
	ssize_t (*store)(struct config_item *, const char *, size_t);
};

configfs_attribute对应的文件含有的是可视化的字符串信息,读写文件时调用结构体里面的show/store函数

struct configfs_bin_attribute {
	struct configfs_attribute cb_attr;	/* std. attribute */
	void *cb_private;			/* for user       */
	size_t cb_max_size;			/* max core size  */
	ssize_t (*read)(struct config_item *, void *, size_t);
	ssize_t (*write)(struct config_item *, const void *, size_t);
};

configfs_bin_attribute对应的文件含有的是二进制信息,读写文件时read/write会被调用

文件所在的目录就是config_item,包括config_group和config_subsytem都是特殊的config_item。config_item下不再有别的目录,我们再看config_item支持的目录操作configfs_item_operations 

struct configfs_item_operations {
	void (*release)(struct config_item *);
	int (*allow_link)(struct config_item *src, struct config_item *target);
	void (*drop_link)(struct config_item *src, struct config_item *target);
};

包括对目录进行链接,可以使用symlink链接到其他目录。

config_group是一类特殊的config_item,它对应有一个目录,同时它支持另外一些目录操作:

struct configfs_group_operations {
	struct config_item *(*make_item)(struct config_group *group, const char *name);
	struct config_group *(*make_group)(struct config_group *group, const char *name);
	int (*commit_item)(struct config_item *item);
	void (*disconnect_notify)(struct config_group *group, struct config_item *item);
	void (*drop_item)(struct config_group *group, struct config_item *item);
};

make_item,支持在当前目录下创建item(make item)和group(make group),对应mkdir

  • 32
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
configfs是用于在Linux内核中创建和管理虚拟文件系统的工具。通过configfs,我们可以使用用户态工具创建虚拟目录及文件,并将其与内核中的驱动程序或功能模块关联起来。 configfs gadget是configfs的一个特性,它允许我们将一个设备模拟为USB gadget,从而实现与主机之间的通信。gadget是指在USB架构中,作为"设备"的一方。使用configfs gadget,我们可以模拟出各种不同类型的USB设备,例如存储设备、网络设备、音频设备等。 为了使用configfs gadget,我们需要编写一些驱动程序以及相应的功能模块,并将其注册到内核中。然后,我们可以通过configfs提供的API,在用户态下创建虚拟文件系统,并将这些驱动程序和功能模块与相应的目录和文件关联起来。这样,当主机连接到模拟的USB gadget时,内核通过configfs可以将对应的驱动程序和功能模块加载并启动,从而实现设备的模拟和通信。 使用configfs gadget的好处是可以快速方便地模拟各种类型的USB设备,方便开发和测试。同时,它也提供了灵活的接口,可以根据需要调整设备的功能和行为。此外,与传统的编写驱动程序并重新编译内核相比,configfs gadget的使用方式更加简洁和灵活。 总之,configfs gadget是一种使用configfs工具在Linux内核中创建和管理虚拟USB设备的方法,它可以快速方便地模拟各种类型的USB设备,并提供灵活的接口进行相关调整和测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bluetangos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值