sysfs设备节点创建分析

本文详细分析了sysfs设备节点的创建流程,包括使用DEVICE_ATTR设置设备属性、创建属性文件(单个和多个)的过程,并探讨了cat操作读取属性文件时的内部机制。重点讲解了sysfs_create_file和sysfs_create_group函数的作用,以及在读取属性文件时如何调用show函数。
摘要由CSDN通过智能技术生成

sysfs设备节点创建分析

sysfs是一种基于ram的文件系统,它提供了一种用于向用户空间展现内核空间里的对象、属性和链接。

1、使用流程

1.1、使用DEVICE_ATTR设置设备属性。

DEVICE_ATTR的定义如下

#define DEVICE_ATTR(_name, _mode, _show, _store) \
	struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

@_name:名称,也就是将在sys fs中生成的文件名称。
@_mode:上述文件的访问权限,与普通文件相同,UGO的格式。
@_show:显示函数,cat该文件时,此函数被调用。
@_store:写函数,echo内容到该文件时,此函数被调用。

#define __ATTR(_name, _mode, _show, _store) {
   				\
	.attr = {
   .name = __stringify(_name),				\
		 .mode = VERIFY_OCTAL_PERMISSIONS(_mode) },		\
	.show	= _show,						\
	.store	= _store,						\
}

例如:

static DEVICE_ATTR(register, S_IWUSR | S_IRUGO, reg_show, reg_store);

将上式展开为

struct device_attribute dev_attr_register = 
{
   
	.attr = {
   .name = __stringify(register),				
		 .mode = VERIFY_OCTAL_PERMISSIONS(S_IWUSR | S_IRUGO) },		
	.show	= reg_show,						
	.store	= reg_store,	
}

device_attribute 的定义为

struct device_attribute {
   
	struct attribute	attr;
	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
			char *buf);
	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
			 const char *buf, size_t count);
};

1.2、创建属性文件

1.2.1 如果只需要创建一个属性文件

直接使用sysfs_create_file创建即可。

static inline int __must_check sysfs_create_file(struct kobject *kobj,
						 const struct attribute *attr)
{
   
	return sysfs_create_file_ns(kobj, attr, NULL);
}
1.2.2 如果需要创建多个属性文件

例如

static DEVICE_ATTR(register,
		S_IWUSR | S_IRUGO,
		reg_show, _reg_store);
static DEVICE_ATTR(hw_en,
		S_IWUSR | S_IRUGO,
		hwen_show, hwen_store);
static DEVICE_ATTR(blink,
		S_IWUSR | S_IRUGO,
		blink_show, blink_store);

如果要创建register、hw_en和blink三个属性文件,则需要使用属性组创建。
首先定义属性数组。

static struct attribute *led_attributes[] = {
   
	&dev_attr_register.attr,
	&dev_attr_hw_en.attr,
	&dev_attr_blink.attr,
	NULL
};

然后定义属性组

static struct attribute_group led_attribute_group = {
   
	.attrs = led_attributes
};

最后使用sysfs_create_group创建多个属性

int sysfs_create_group(struct kobject *kobj,
		       const struct attribute_group *grp)
{
   
	return internal_create_group(kobj, 0, grp);
}

这样就可以在sys路径下创建出相应的属性文件。

2、创建过程分析

2.1 创建一个属性文件

由第一节可知创建一个属性文件的起始函数为

int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
			 const void *ns)
{
   
	kuid_t uid;
	kgid_t gid;

	if (WARN_ON(!kobj || !kobj->sd || !attr))
		return -EINVAL;

	kobject_get_ownership(kobj, &uid, &gid);
	return sysfs_add_file_mode_ns(kobj->sd, attr, false, attr->mode,
				      uid, gid, ns);

}

这里会用到sysfs_add_file_mode_ns。而创建多个属性文件同样会用到这个函数。

2.2 创建多个属性文件

由1.2.2可知创建多个属性文件的起始入口为

// fs\sysfs\group.c

int sysfs_create_group(struct kobject *kobj,
		       const struct attribute_group *grp)
{
   
	return internal_create_group(kobj, 0, grp);
}
// fs\sysfs\group.c

static int internal_create_group(struct kobject *kobj, int update,
				 const struct attribute_group *grp)
{
   
	struct kernfs_node *kn;
	kuid_t uid;
	kgid_t gid;
	int error;

	if (WARN_ON(!kobj || (!update && !kobj->sd)))
		return -EINVAL;

	/* Updates may happen before the object has been instantiated */
	if (unlikely(update && !kobj->sd))
		return -EINVAL;
	if (!grp->attrs && !grp->bin_attrs) {
   
		WARN(1, "sysfs: (bin_)attrs not set by subsystem for group: %s/%s\n",
			kobj->name, grp->name ?
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值