(转)Linux 文件系统:procfs, sysfs, debugfs 用法简介
网址:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/
1 前言
内核中有三个常用的伪文件系统: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.
它们都用于Linux内核和用户空间的数据交换,但是适用的场景有所差异:
- procfs 历史最早,最初就是用来跟内核交互的唯一方式,用来获取处理器、内存、设备驱动、进程等各种信息。
- sysfs 跟 kobject 框架紧密联系,而 kobject 是为设备驱动模型而存在的,所以 sysfs 是为设备驱动服务的。
- debugfs 从名字来看就是为debug而生,所以更加灵活。
它们仨的挂载方式类似,做个实验:
$ sudo mkdir /tmp/{proc,sys,debug}$ sudo mount -t proc nondev /tmp/proc/$ sudo mount -t sys nondev /tmp/sys/$ sudo mount -t debugfs nondev /tmp/debug/
不过,默认情况下,它们分别挂载在/proc,/sys/,/sys/kernel/debug/。
下面简单介绍这三个文件系统的用法。在介绍之前,请记下他们的官方文档:
- procfs — Documentation/filesystems/proc.txt
- sysfs — Documentation/filesystems/sysfs.txt
- debugfs — Documentation/filesystems/debugfs.txt
2 debugfs
API说明
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)struct dentry *debugfs_create_file(const char *name, umode_t mode,struct dentry *parent, void *data,const struct file_operations *fops)
参考实例
drivers/base/power/wakeup.c:
/*** wakeup_sources_stats_show - Print wakeup sources statistics information.* @m: seq_file to print the statistics into.*/static int wakeup_sources_stats_show(struct seq_file *m, void *unused){struct wakeup_source *ws;seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t""expire_count\tactive_since\ttotal_time\tmax_time\t""last_change\tprevent_suspend_time\n");rcu_read_lock();list_for_each_entry_rcu(ws, &wakeup_sources, entry)print_wakeup_source_stats(m, ws);rcu_read_unlock();return 0;}static int wakeup_sources_stats_open(struct inode *inode, struct file *file){return single_open(file, wakeup_sources_stats_show, NULL);}static const struct file_operations wakeup_sources_stats_fops = {.owner = THIS_MODULE,.open = wakeup_sources_stats_open,.read = seq_read,.llseek = seq_lseek,.release = single_release,};static int __init wakeup_sources_debugfs_init(void){wakeup_sources_stats_dentry = debugfs_create_file("wakeup_sources",S_IRUGO, NULL, NULL, &wakeup_sources_stats_fops);return 0;}
创建完的接口
/sys/kernel/debug/wakup_sources
给接口添加多级目录
上述接口直接创建在
debugfs根目录(/sys/kernel/debug)下,所以debugfs_create_file的parent参数被设置成了NULL,如果要加一级目录,则可以先用debugfs_create_dir创建一级目录,例如,要创建:/sys/kernel/debug/power/wakeup_sources的话,则需要:struct dentry *power;int err = -ENOMEM;power = debugfs_create_dir("power", NULL);if (!power)return err;wakeup_sources_stats_dentry = debugfs_create_file("wakeup_sources",S_IRUGO, power, NULL, &wakeup_sources_stats_fops);
3 procfs
API说明
static inline struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)static inline struct proc_dir_entry *proc_create(const char *name, umode_t mode,struct proc_dir_entry *parent, const struct file_operations *proc_fops)
参考实例
在上面例子的基础上,可以添加如下语句:
static int __init wakeup_sources_debugfs_init(void){proc_create("wakelocks", S_IFREG | S_IRUGO, NULL, &wakeup_sources_stats_fops);return 0;}
创建后的接口
/proc/wakelocks
给接口添加多级目录
这样创建的接口用起来跟
/sys/kernel/debug/wakeup_sources没有任何差异,类似地,如果要加一级目录,例如/proc/power/wakelocks,则可以:struct proc_dir_entry *power;int err = -ENOMEM;power = proc_mkdir("power", NULL);if (!power)return err;proc_create("wakelocks", S_IFREG | S_IRUGO, power, &wakeup_sources_stats_fops);
proc_mkdir用法跟debugfs_create_dir几无差异。
4 sysfs
API说明
struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)static inline int sysfs_create_link(struct kobject *kobj, struct kobject *target, const char *name)int device_create_file(struct device *dev, const struct device_attribute *attr)
参考实例
在
/sys/power下创建一个 wakelocks 节点,用于读/写一个字符串。static char test_str[11];static ssize_t show_wakelocks(struct kobject *kobj, struct attribute *attr, char *buf){int ret;ret = snprintf(buf, 10, "%s\n", test_str);return ret;}static ssize_t store_wakelocks(struct kobject *kobj, struct attribute *attr,const char *buf, size_t count){int tmp;ret = sscanf(buf, "%10s", test_str);if (ret != 1)return -EINVAL;return count;}define_one_global_rw(wakelocks);static int __init wakelocks_init(void){int ret;ret = sysfs_create_file(power_kobj, &wakelocks.attr);}
创建后的节点
/sys/power/test_node
给接口添加多级目录
咱们上面其实已经把 test_node 创建在
/sys/power目录下,而非根目录/sys下,而参数 power_kobj 为内核已经在kernel/power/main.c创建的kobject对象。struct kobject *power_kobj;power_kobj = kobject_create_and_add("power", NULL);if (!power_kobj)return -ENOMEM;
在
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创建节点或者节点群。
5 小结
通过比较发现,上述三个文件系统的 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 来创建节点。
(转)Linux 文件系统:procfs, sysfs, debugfs 用法简介的更多相关文章
- Linux驱动开发3——devfs udev procfs sysfs debugfs傻傻地分不清楚
Linux调试文件系统 1.1.procfs 早期的Linux内核中,内核通过procfs输出调试信息,可以在用户态通过读写procfs节点与内核进行交互,用来获取处理器.内存.设备驱动.进程等各种信 ...
- [转帖]linux lsof 用法简介
linux lsof 用法简介 https://www.cnblogs.com/saneri/p/5333333.html 1.简介: lsof(list open files)是一个列出当前系统打开 ...
- linux 文件系统简介
linux文件系统简介 文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基 ...
- linux文件系统简介
文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基本原理.文件存储结构.软链接 ...
- Linux文件系统简介及常用命令
在linux系统中一切皆是文件,下面简要总结了一下linux文件系统中分区类型.文件系统类型以及常用命令. 一.分区类型1.主分区:最多只能有四个2.扩展分区:只能有一个,也可以看做是主分区的一种.即 ...
- Linux文件系统简介----转载
原文地址:Linux文件系统 文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载 ...
- 新一代 Linux 文件系统 btrfs 简介
https://www.ibm.com/developerworks/cn/linux/l-cn-btrfs/ Btrfs 简介 文件系统似乎是内核中比较稳定的部分,多年来,人们一直使用 ext2/3 ...
- 【转载】linux文件系统简介
文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基本原理.文件存储结构.软链接 ...
- 存储那些事儿(二): 下一代Linux文件系统BTRFS简介
BTRFS,通常念成 Butter FS,Better FS 或B-tree FS.下一代的Linux文件系统. 它基于写时拷贝(copy-on-write),支持高效的snapshot和clone. ...
随机推荐
- .NET学习笔记(1)— C#学习路线图
目录 一:引言 二:.NET技术体系 三:常用工具汇总 四:学习资源汇总 五:书籍推荐 六:关于阅读技术书籍的经验 七:总结 一:引言 因为工作调整,从PHP开发零基础转型到.NET开发,前期没有 ...
- IOS 解析XML--使用NSXML
一.解析文档顺序触发的函数 1.parserDidStartDocument,在文档的时候触发. 2.parser:didStartElement:namespaceURI:qualifiedName ...
- 学习之spring属性文件注入
package com.my.proper; import org.springframework.beans.factory.annotation.Value; import org.springf ...
- Linux 查看系统版本及位数
1. 查看内核版本命令: 1) [root@www ~]# cat /proc/version Linux version 2.6.9-22.ELsmp (bhcompile@crowe.dev ...
- css3学习笔记之图片
圆角图片 border-radius: 圆角图片: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <!DOCTYPE html> <htm ...
- Hyper-V 虚拟机连接外部网络
Hyper-V创建好虚拟机之后,在默认配置下是没有网络连接的,这个时候就需要进行简单的配置,即可让虚拟机连接外部网络: 在Hyper-V管理器中,右键点击后出现菜单,选择"虚拟交换机管理器& ...
- sphinx 占用大量内存
http://www.coreseek.com/forum/2_1847_0.html(转) 刚开始没改下面2句时,内存占用比较多,在生成index的时候就占用了! 下面是解决方法: 每个索引中写上 ...
- 第七章 探秘Qt的核心机制-信号与槽
第七章 探秘Qt的核心机制-信号与槽 注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用 ...
- SVN全量备份+增量备份脚本
一.全量备份 环境:一台主SVN,一台备SVN(主要提供备份功能),后续可通过钩子脚本进行实时备份,后续发给大家. 工作原理:通过svn的hotcopy命令过行热备份,并进行一系列的检查,备份后通过r ...
- kali使用随笔
1.kali 默认禁用网络服务,显示设备未托管.需要在/etc/NetworkManager/NetworkManager.conf将managed=false修改为true,重启电脑. 2.自己利用 ...