内核sysfs的使用简介

sysfs在设备文件创建中的作用

内核注册设备驱动时采用的是cdev_add接口,但是对于应用层来说,想要访问设备文件,必须先要创建一个对应设备号的设备文件才可以,比如:

sudo mknod dev/null c 1 3

上面是一种古老的方式,所有的设备驱动都要手动创建设备文件去访问,当前最流行的方法是利用上层的udev/mdev工具来帮助我们实现这个功能。mdev命令常用在嵌入式系统中,通过编译busybox之后即可拥有该工具。使用如下命令可以启动mdev自动检测设备驱动并创建设备文件:

cdev -s

那么既然介绍到这里,那么这个工具是利用什么原理来实现这个功能的呢?设备驱动代码需要生成相关的sysfs设备节点,只有添加了sysfs设备节点的驱动才能够被上层工具检测到并自动生成设备文件。举个驱动代码为例,首先会申请设备号并且在内核层创建设备:

rc = alloc_chrdev_region(&synx_dev->dev, 0, 1, SYNX_DEVICE_NAME);
if (rc < 0) {
    pr_err("region allocation failed\n");
    goto alloc_fail;
}

cdev_init(&synx_dev->cdev, &synx_fops);
synx_dev->cdev.owner = THIS_MODULE;
rc = cdev_add(&synx_dev->cdev, synx_dev->dev, 1);
if (rc < 0) {
    pr_err("device registation failed\n");
    goto reg_fail;
}

创建完设备后,并不会自动生成设备文件,需要生成sysfs设备文件:

synx_dev->class = class_create(THIS_MODULE, SYNX_DEVICE_NAME);
device_create(synx_dev->class, NULL, synx_dev->dev,
    NULL, SYNX_DEVICE_NAME);

device_create 会在sysfs中创建对应的文件节点,从而可以被上层的udev和mdev检测到并创建对应的设备文件。

device_create --> device_create_vargs --> device_create_groups_vargs --> device_add --> kobject_add
-->kobject_add_varg --> kobject_add_internal --> create_dir --> sysfs_create_dir_ns --> kernfs_create_dir_ns

创建完成后可以在sysfs节点中查看对应的设备节点目录,并且在/dev目录下生成设备文件:

/sys/class/[CLASS_NAME]/[DEVICE_NAME]

/dev/[DEVICE_NAME]

创建device attribute文件的两种方法

sysfs除了用于生成设备节点,还可以用来传递驱动信息到用户空间。有两种方法来完成这个功能:
第一种方式是使用如下接口来创建,这个接口每次只能创建一个文件节点:

int device_create_file(struct device *dev,
        const struct device_attribute *attr);

第二种方式是使用sysfs相关的接口来创建,可以用于批量创建attribute文件节点:


int sysfs_create_group(struct kobject *kobj,
               const struct attribute_group *grp);

举个实例:

static ssize_t show_debug(struct device *dev,
							struct device_attribute *attr, char *buf)
{

	return sprintf(buf, "debug value:%d\n", debug_value);
}

static ssize_t store_debug(struct device *dev,
							struct device_attribute *attr,
							const char *buf, size_t size)
{
	sscanf(buf, "%d", &debug_value);
	return size;
}
static DEVICE_ATTR(debug, 0660, show_debug, store_debug);

static struct attribute *ramchar_attributes[] = {
    &dev_attr_debug.attr,
    NULL
};

static const struct attribute_group ramchar_attr_group = {
    .attrs = ramchar_attributes,
};

static int __init ramdev_init(void)
{
    ......
    rc = sysfs_create_group(&ramdev->device->kobj, &ramchar_attr_group);
	if (rc < 0) {
		ramdev_err("Failed to create attribute sysfs\n");
		goto cdev_fail;
	}
    ......
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值