1./proc 文件系统概述

/proc 文件系统是由软件创建,被内核用来向外界报告信息的一个文件系统。/proc 下面的每一个文件都和一个内核函数相关联,当文件的被读取时,与之对应的内核函数用于产生文件的内容。我们已经见到了很多这样的文件,例如,/proc/modules 总是返回当前内核中加载的模块。

/proc 广泛的应用在 linux 文件系统中,现代 linux 发行版上的许多应用程序,例如 ps ,top 和 uptime 都从 /proc 获取他们所需要的信息。一些驱动程序也通过 /proc 文件系统报告信息,当然你的驱动程序也可以这么做。 /proc 文件系统是动态的,所以你的模块可以在任何时候添加或者删除入口。完全特征的 /proc 入口可能会是一个复杂的猛兽,它们既可以读也可以写。然而,大多数时候,/proc 中的文件是只读的。这里考虑的是只读的 /proc 文件。

然而,在继续之前,必须强调在 /proc 下面添加文件是不提倡的。/proc 文件系统被内核开发者看作是不可控制的混乱,这和它最初的目的--报告系统中运行的进程的信息相差十万八千里。在新的代码中推荐的获取信息的方式是通过 sysfs 。但是,使用 sysfs 是需要对 linux 设备模型有一个理解。并且,/proc 下面的文件较容易创建,并且完全符合调试的目的,所以才会学习 /proc 文件系统。

2.创建 /proc 文件

如果你定义了一个 read_proc 函数,你需要将它和 /proc 层次中的入口联系起来。这是通过一个叫做 create_proc_read_entry 的函数来实现的,这个函数的函数原型如下:

struct proc_dir_entry *create_proc_read_entry(const char *name,mode_t mode,struct proc_dir_entry *base,read_proc_t *read_proc,void *data);

上面的函数原型中,name 就是要创建的文件的名字;mode 就是文件的保护掩码,可以使用 0 来使用系统默认的掩码;base 指定了创建的文件所在的目录,如果 base 为 NULL,创建的文件就存在于 /proc 目录之下;read_proc 就是实现这个文件的函数;data 参数被内核忽略,但是却被传递给 read_proc 函数。举一个例子:

create_proc_read_entry("scullmem", 0/*default mode*/, NULL /*parent dir*/, scull_read_procmem, NULL /*client data*/);

这个例子中,我们在 /proc 下面创建了一个文件,名字为 scullmem,采用的是系统默认的保护权限。

目录入口指针可以用来在 /proc 下创建整个目录架构,然而,注意将一个文件放到 /proc 子目录中的一个更加容易的做法是将子目录的名字作为要创建的新文件名字的一部分路径,只要那个子目录已经存在。例如一个经常被忽略的惯例就是和驱动程序相关的 /proc 文件应该放到一个 driver 子目录中。例如,上面的例子中,我们想要将所创建的文件 scullmem 放到 driver 中,只需要将第一个参数修改为 "driver/scullmem" 就可以了。

/proc 中文件在模块被卸载的时候应该被删除。remove_proc_entry 所做的事情和 create_proc_read_entry 所做的事情相反。例如:

remove_proc_entry("scullmem",NULL /*parent dir*/);

不能成功的移除文件将导致这个文件在不合适的时候被调用,或者是,模块被卸载后,内核就崩溃了。当向上面一样使用 /proc 的时候,必须记住几个麻烦的事——难怪现在不推荐使用这种方式了。最重要的问题就是在删除 /proc 文件的时候了,在删除的时候文件可能仍然在使用。因为 /proc 文件没有相关的所有者,所以使用它们的时候并不会对引用计数起作用。这个问题可以简单的通过在删除文件之前使用下面的命令引起:

sleep 100  < /proc/myfile

另外一个问题是注册了两个一样名字的文件。内核信任驱动程序,并不检查文件的名字是否备注册过,所以如果你不小心,就可能会注册多个相同名字的文件。这就像在教室里发生的著名的问题一样,这些文件不能区分,不管是你在访问它们还是调用remove_proc_entry的时候。

3.在 /proc中实现文件

所有使用 /proc 的模块应该包括 <linux/proc_fs.h> 头文件来定义合适的函数。创建一个只读的 /proc 文件,你的驱动程序必须实现一个函数,当这个文件被读时,来产生一些数据。当一些进程使用 read 函数读取文件的时候,请求就通过这个函数到达了你的模块。我们会首先看一下这个函数,并且之后介绍注册的接口。当一个进程读取 /proc 文件的时候,内核就分配了一页的内存,驱动程序可以将要返回给用户空间的数据写到这个页里面。那个缓存被传递给了你的 read_proc 函数。read_proc 函数的原型如下:

int (*read_proc)(char *page,char **start,off_t offset,int count,int *eof,void *data);

参数 page 是缓冲区的指针,你可以往里面写入数据;start 被函数用来说明感兴趣的数据被写到了页的位置。offset 和 count 与 read 函数的参数意义相同;eof 指向了一个整数,必须由驱动程序来设定报告没有返回的数据了,data 是依赖于特定的驱动的数据指针,你可以用来作为内部记账。

这个函数应该返回写入到页缓冲区中的数据字节数。就像 read 函数一样。其它的输出是 *eof 和 *start 。eof 是一个简单的标记,但是 start 的使用方法是有写复杂的,它的目的视为了帮助实现大的(超过一页)的 /proc 文件。start 参数并不常用,它的目的使用来指示返回给用户空间的住局在一页中的哪个位置。当 read_proc 函数被调用的时候,*start 参数将会被设置为 NULL。如果你保留它为 NULL 的话,内核会假设数据放到页里面时,参数 offset 为 0。换句话说,内核假设了一个头脑简单的 read_proc 版本,它把虚拟文件的所有内容写到页里面,而忽略了 offset 参数。相反,如果给 *start 设置了一个不是 NULL 的值,内核就假设由 *start 指向的数据将 offset 考虑在内,并且已经准备好返回给用户空间了。一般来说,简单的 proc_read 方法返回很少量的数据常常忽略了 *start 参数。更加复杂的方法才会设置页的 *start 的值,并且仅仅将数据放到所请求的 offset 那里。

4.实例

在这里,我们写了一个简单的例子来演示一下 /proc 的使用:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>int read_proc(char *page,char **start,off_t offset,int count,int *eof,void *data);static int __init test_proc_init(void)
{create_proc_read_entry("read_proc",0,NULL,read_proc,NULL);return 0;
}static void __exit test_proc_exit(void)
{remove_proc_entry("read_proc",NULL);
}int read_proc(char *page,char **start,off_t offset,int count,int *eof,void *data)
{int len = sprintf(page,"%s\n","hello world");return len;
}module_init(test_proc_init);
module_exit(test_proc_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("wangxq");

当插入这个模块到内核之后,使用命令:

cat /proc/read_proc

就会看到输出 hello world。

linux中proc文件系统 -- ldd3读书笔记相关推荐

  1. Linux Shell脚本攻略 读书笔记

    内容目录: 嗨,Echo一下 给终端来点颜色 shell的控制结构 算术比较 目录操作 网站下载 tar 归档工具 rsync 备份系统快照 ftp自动传输 磁盘管理 故障排查 使用syslog记录日 ...

  2. Linux中/proc目录下文件详解

    Linux中/proc目录下文件详解(一) 声明:可以自由转载本文,但请务必保留本文的完整性. 作者:张子坚 email:zhangzijian@163.com 说明:本文所涉及示例均在fedora ...

  3. Linux中/proc目录下文件详解(二)

    Linux中/proc目录下文件详解(二) /proc/mdstat文件 这个文件包含了由md设备驱动程序控制的RAID设备信息. 示例: [root@localhost ~]# cat /proc/ ...

  4. linux 中/proc 详解

    proc 文件系统   在Linux中有额外的机制可以为内核和内核模块将信息发送给进程-- /proc 文件系统.最初设计的目的是允许更方便的对进程信息进行访问(因此得名),现在它被每一个有有趣的东西 ...

  5. linux 内核模块 proc,Linux 内核模块 proc文件系统.pdf

    Linux内核模块 proc文件系统 Linux内核模块 §  内核模块是内核的扩展,它供了在内核运 行过程中动态加载的特性. §  模块被加载进系统后,就在内核态下运行了, 成了内核的一部分,可以读 ...

  6. Linux中/proc目录下文件详解 /proc/devices文件 /proc/modules文件

    http://blog.chinaunix.net/uid-10449864-id-2956854.html 原来对linux系统中的/proc目录不是很了解,只知道可以查看cpu,内存等相关的信息, ...

  7. 在Linux中查找文件系统类型的7种方法(ext2,ext3或ext4)

    文件系统是在存储磁盘或分区上命名,存储,检索和更新文件的方式.文件在磁盘上的组织方式. 文件系统分为两个部分:用户数据和元数据(文件名,创建时间,修改时间,大小和在目录层次结构中的位置等). 在本指南 ...

  8. linux在当前目录下创建pic目录,Linux中/proc目录下文件详解

    文章转自: Linux中/proc目录下文件详解(一) ------------------------------------------------------------------------ ...

  9. Linux中/proc目录下文件详解(zt)

    Linux中/proc目录下文件详解(一) 声明:可以自由转载本文,但请务必保留本文的完整性. 作者:张子坚 email:zhangzijian@163.com 说明:本文所涉及示例均在fedora ...

最新文章

  1. 浏览器对象模型:window对象2
  2. 微服务系列(七):将单体应用改造为微服务
  3. 龙邱树莓派Raspberry Pi 扩展板电路及其相关实验
  4. spring websocket源码分析
  5. 创客运动引发第三次工业革命
  6. 使用IDEA的Spring Initializr创建SpringBoot工程
  7. 查询字段是date类型的数据
  8. 7.25 Ext JS下拉单选框(Combobox,TagFied)使用及疑难问题解决
  9. 学成在线day13,HLS视频文件处理,FFmpeg,画面清晰度的码率, H5播放器video.js,媒资管理,断点上传文件和合并文件,WebUploader百度上传插件,
  10. 图像纹理特征总体简述
  11. linux下dft计算标准函数,FFT/DFT计算方法
  12. 2018-2019年全球专业服务机器人销售额增长32%,达到112亿美元
  13. 腾讯微云和坚果云哪个好用?
  14. 第四章(第二节)没有人,在年少时想成为一个普通人
  15. 零基础做油管搬运二创项目的正确方式,短视频小白玩家套利的可能
  16. GitHub爆款项目,去马赛克软件Depix使用
  17. 制作Win10系统安装U盘,安装纯净版Win10的通用教程
  18. 泰肯星球(Token Planets)基于EOS区块链技术的虚拟游戏
  19. ORB-SLAM3从理论到代码实现(一):Optimizer单帧优化
  20. STM32的标准库及其使用

热门文章

  1. Shut Down(or Closing) Your Windows and Open The Unix
  2. 数据结构 3优先队列(堆)
  3. [转载] Pandas:DataFrame对象的基础操作
  4. [转载] Python中对 Excel 的相关详细操作(读取、写入、指定行、指定列、新增sheet工作表)
  5. c语言里面你不知道的break与switch,contiune的用法
  6. python3.7安装wxPython后导入wx报错
  7. 何登成 MYSQL 博客
  8. 使用doxygen查看文件包含关系图
  9. 为什么需要使用Git客户端?
  10. 数据结构上机实践第14周项目2 - 二叉树排序树中查找的路径