sysfs/procfs/debugfs简介

Linux内核提供了三种内存文件系统,分别是sysfs、debugfs、procfs,驱动工程师可以通过任意的一种文件系统向用户空间传递信息。

Sysfs的挂载点为/sys
Debugfs的挂载点为/sys/kernel/debug
Procfs的挂载点为/proc

这三种形式的文件系统都是内存文件系统,他们中的信息只存在于内存中,下电后即消失。他们的出现旨在提供一种与用户空间交互信息的方式。

这三种类型文件系统的实现在内核中的:/kernel/fs/目录下。

如何使用它们呢?
Sysfs
我们知道在进行驱动注册时,对于一个驱动文件的生成,我们两个步骤:

1.调用cdev_add函数注册,函数的作用主要是把file_operations与dev的设备号关联起来。
2.要调用device_create(&class, …)生成相对应的/sysfs目录和/dev设备文件。需要一个传入class和所需要的设备号。

device_create函数内部会调用到device_add函数,这个函数是生成设备文件的关键,实质上它是整个设备模型注册的关键。在device_add函数需要传入参数struct device,会在/sys/device目录下生成相应的sys文件,同时会判断device结构中的devt变量是否可用,如果可用才会调用devtmpfs_create_node(dev);在/dev目录下生成对应的设备文件。所以说device_add是否会生成设备文件需要根据device结构体中是否传入了设备号来决定的。
由上所写,除了调用device_create来生成对应的设备文件以外,我们也可以自己初始化device结构体后调用device_add函数来生成设备文件。

如:
evdev->dev.devt = MKDEV(INPUT_MAJOR, minor);
evdev->dev.class = &input_class;
evdev->dev.parent = &dev->dev;
evdev->dev.release = evdev_free;
device_initialize(&evdev->dev);
cdev_init(&evdev->cdev, &evdev_fops);
evdev->cdev.kobj.parent = &evdev->dev.kobj;
error = cdev_add(&evdev->cdev, evdev->dev.devt, 1);
if (error)
goto err_unregister_handle;

error = device_add(&evdev->dev);
if (error)
    goto err_cleanup_evdev;

evdev->cdev.kobj.parent = &evdev->dev.kobj;这一步的作用是在sysfs的该device目录中生成对应的dev文件。该文件内容就是设备号。

在驱动注册时调用device_create(&class, …)只会在sysfs中生成对应的一个设备目录,而我们更多的时候需要把一些驱动信息传递到用户层,这一步是通过在该目录中生成属性文件的方式来实现的。

接下来我们看看属性文件是怎么生成的。

1.device_create_file单个生成接口:
针对struct device_attribute结构体,生成sysfs中的设备属性文件,可以使用下面的方法:
int device_create_file ( struct device * dev,
const struct device_attribute * attr);
其中会调用到sysfs_create_file函数来生成sysfs属性文件,此接口用于生成单个属性文件。

2.sysfs_create_group批量生成接口:
例如:
首先定义struct device_attribute结构体,如果需要的属性为polling的话定义如下:
static DEVICE_ATTR(polling, S_IRUGO | S_IWUSR, show_polling, set_polling);

封装struct attribute结构体,注意成员变量是&dev_attr_polling.attr.
static struct attribute *dev_attrs[] = {
&dev_attr_polling.attr,
NULL,
};
.然后再封装成struct attribute_group
static struct attribute_group dev_attr_grp = {
.attrs = dev_attrs,
};
在利用sysfs_create_group(&pdev->dev.kobj, &dev_attr_grp);创建接口

这里介绍了两种方法,当然除了这两种,你也可以提前静态的定义struct device_type,在struct device中赋值后调用device_add接口,来一次性生成设备目录和设备属性文件。

Procfs
这种也比较简单,以一个例子来说明它的使用方法吧。

static int __init input_proc_init(void)
{
struct proc_dir_entry *entry;

proc_bus_input_dir = proc_mkdir("bus/input", NULL);
if (!proc_bus_input_dir)
    return -ENOMEM;

entry = proc_create("devices", 0, proc_bus_input_dir,
            &input_devices_fileops);
if (!entry)
    goto fail1;

entry = proc_create("handlers", 0, proc_bus_input_dir,
            &input_handlers_fileops);
if (!entry)
    goto fail2;

return 0;

fail2: remove_proc_entry(“devices”, proc_bus_input_dir);
fail1: remove_proc_entry(“bus/input”, NULL);
return -ENOMEM;
}

Debugfs

Debugfs和procfs差不多,主要是用来调试时使用,这部分也没什么好讲的,大家参考gpio子系统中的实现自行研阅吧

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值