目录 []
前言
内核中有三个常用的伪文件系统:procfs,debugfs和sysfs。
- procfs — The proc filesystem is a pseudo-filesystem which provides an interface to kernel data structures.
- sysfs — The filesystem for exporting kernel objects.
- debugfs — Debugfs exists as a simple way for kernel developers to make information available to user space.
它们都用于内核和用户空间的数据交换,但是适用的场景有所差异:
- procfs 历史最早,最初就是用来跟内核交互的唯一方式,用来获取处理器、内存、设备驱动、进程等各种信息。
- sysfs 跟 kobject 框架紧密联系,而 kobject 是为设备驱动模型而存在的,所以 sysfs 是为设备驱动服务的。
- debugfs 从名字来看就是为debug而生,所以更加灵活。
它们仨的挂载方式类似,做个实验:
不过,默认情况下,它们分别挂载在/proc,/sys/,/sys/kernel/debug/。
下面简单介绍这三个文件系统的用法。在介绍之前,请记下他们的官方文档:
- procfs — Documentation/filesystems/proc.txt
- sysfs — Documentation/filesystems/sysfs.txt
- debugfs — Documentation/filesystems/debugfs.txt
debugfs
-
API说明
-
参考实例
drivers/base/power/wakeup.c:
-
创建完的接口
-
给接口添加多级目录
上述接口直接创建在 debugfs 根目录(/sys/kernel/debug)下,所以 debugfs_create_file的parent参数被设置成了NULL,如果要加一级目录,则可以先用 debugfs_create_dir 创建一级目录,例如,要创建:/sys/kernel/debug/power/wakeup_sources 的话,则需要:
procfs
-
API说明
-
参考实例
在上面例子的基础上,可以添加如下语句:
-
创建后的接口
-
给接口添加多级目录
这样创建的接口用起来跟 /sys/kernel/debug/wakeup_sources 没有任何差异,类似地,如果要加一级目录,例如 /proc/power/wakelocks,则可以:
proc_mkdir 用法跟 debugfs_create_dir 几无差异。
sysfs
-
API说明
-
参考实例
在 /sys/power 下创建一个 wakelocks 节点,用于读/写一个字符串。
-
创建后的节点
-
给接口添加多级目录
咱们上面其实已经把 test_node 创建在 /sys/power 目录下,而非根目录 /sys 下,而参数 power_kobj 为内核已经在 kernel/power/main.c 创建的kobject对象。
在 sysfs 中,有另外一个常见用法,那就是在一个 kobject 对应的目录下创建一个符号(属性文件)指向另外一个 kobject 对应的目录,通常这个是为了方便记忆和访问。这个API是sysfs_create_link。
这种创建符号链接方法其实有一个很特殊的实例,那就是在驱动模型里头,有一个 class 的概念,它把挂在不同总线上,但是实现类似功能的设备进行归类,比如说 input 类,backlight 类等。
如果设备属于一个现存的类,比如 backlight,那么可以用 backlight_device_register 创建,如果是 I2C 设备,会先在I2C下创建 sysfs 访问节点,并创建一个符号链接到 backlight 类所属的目录下。
当然,如果没有找到设备能挂的直观的类,也可以用 class_create 创建类,设备类通常会有一组默认的设备操作接口,例如 backlight 类有 bl_device_attributes,如果要创建更多的设备特定的节点,可以用 device_create_file 或者 device_add_groups 创建节点或者节点群。
小结
通过比较发现,上述三个文件系统的 API 用法类似,而其中 debugfs 和 procfs 几乎有相同的参数,用的主要结构体是 struct file_operations,蛮多操作可以用 seq_* 家族的函数来实现。而 sysfs 则用到比较简单一些的 struct global_attr 结构体。对于提供给用户空间的节点,都可以轻松实现读写操作。
在创建目录方面,debugfs 和 procfs 类似,且比较简单。而 sysfs 要创建一级目录,需要先创建一个 kobject 对象。
为了简化设备模型依据总线创建的访问节点路径,sysfs 提供了API用于创建更简易的符号链接,可以创建到自己指定的目录下,也可以用设备类(Class)提供的API创建到设备类所属的目录下。
对于 sysfs,由于 kobject 与 device 的一对一依存关系,也可以直接用 device_create_file 来创建节点。