一文讲解Linux proc文件系统介绍
最初开发/proc文件系统是为了提供有关系统中进程的信息。但是由于这个文件系统非常有用,因此内核中的很多元素也开始使用它来报告信息,或启用动态运行时配置。 /proc文件系统包含了一些目录(用作组织信息的方式)和虚拟文件。虚拟文件可以向用户呈现内核中的一些信息,也可以用作一种从用户空间向内核发送信息的手段。实际上我们并不会同时需要实现这两点,但是本文将向您展示如何配置这个文件系统进行输入和输出。 尽管像本文这样短小的一篇文章无法详细介绍/proc的所有用法,但是它依然对这两种用法进行了展示,从而可以让我们体会一下/proc是多么强大。图1是对/proc中部分元素进行一次交互查询的结果。它显示的是/proc文件系统的根目录中的内容。注意,在左边是一系列数字编号的文件。每个实际上都是一个目录,表示系统中的一个进程。由于在GNU/Linux中创建的第一个进程是init进程,因此它的process-id为1。然后对这个目录执行一个 ls命令,这会显示很多文件。每个文件都提供了有关这个特殊进程的详细信息。例如,要查看init的command-line项的内容,只需对cmdline文件执行cat命令。

proc中另外一些有趣的文件有:cpuinfo,它标识了处理器的类型和速度;pci:显示在PCI总线上找到的设备;modules:标识了当前加载到内核中的模块。
图2展示了对/proc中的一个虚拟文件进行读写的过程。这个例子首先检查内核的TCP/IP栈中的IP转发的目前设置,然后再启用这种功能。

另外,我们还可以使用sysctl来配置这些内核条目。
顺便说一下,/proc文件系统并不是GNU/Linux系统中的惟一一个虚拟文件系统。在这种系统上,sysfs是一个与/proc类似的文件系统,但是它的组织更好(从 /proc 中学习了很多教训)。不过 /proc 已经确立了自己的地位,因此即使sysfs与/proc相比有一些优点,/proc也依然会存在。还有一个debugfs文件系统,不过(顾名思义)它提供的更多是调试接口。debugfs的一个优点是它将一个值导出给用户空间非常简单(实际上这不过是一个调用而已)。
【文章福利】小编推荐自己的Linux内核技术交流群:【891587639】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!(含视频教程、电子书、实战项目及代码)


/proc目录下常见的文件介绍:
/proc/apm 高级电源管理(APM)版本信息及电池相关状态信息,通常由apm命令使用; proc/buddyinfo 用于诊断内存碎片问题的相关信息文件; /proc/cmdline 在启动内核时传递至内核的相关参数信息,这些信息通常由lilo或grub等启动管理工具进行传递;

/proc/cpuinfo 处理器的相关信息的文件; /proc/crypto 系统上已安装的内核使用的密码算法及每个算法的详细信息列表; /proc/devices 系统已经加载的所有块设备和字符设备的信息,包含主设备号和设备组(与主设备号对应的设备类型)名; /proc/dma 每个正在使用且注册的ISA DMA通道的信息列表; /proc/fb 帧缓冲设备列表文件,包含帧缓冲设备的设备号和相关驱动信息; /proc/filesystems 当前被内核支持的文件系统类型列表文件,被标示为nodev的文件系统表示不需要块设备的支持;通常mount一个设备时,如果没有指定文件系统类型将通过此文件来决定其所需文件系统的类型; /proc/interrupts ARM体系架构系统上每个IRQ相关的中断号列表;

/proc/iomem 每个物理设备上的记忆体(RAM或者ROM)在系统内存中的映射信息; /proc/kmsg 此文件用来保存由内核输出的信息,通常由/sbin/klogd或/bin/dmsg等程序使用,不要试图使用查看命令打开此文件; /proc/meminfo 系统中关于当前内存的利用状况等的信息,常由free命令使用;可以使用文件查看命令直接读取此文件,其内容显示为两列,前者为统计属性,后者为对应的值; /proc/modules 当前装入内核的所有模块名称列表,可以由lsmod命令使用,也可以直接查看;如下所示,其中第一列表示模块名,第二列表示此模块占用内存空间大小,第三列表示此模块有多少实例被装入,第四列表示此模块依赖于其它哪些模块,第五列表示此模块的装载状态(Live:已经装入;Loading:正在装入;Unloading:正在卸载),第六列表示此模块在内核内存(kernel memory)中的偏移量; /proc/partitions 块设备每个分区的主设备号(major)和次设备号(minor)等信息,同时包括每个分区所包含的块(block)数目,如下图所示;

/proc/slabinfo 在内核中频繁使用的对象(如inode、dentry等)都有自己的cache,即slab pool,而/proc/slabinfo文件列出了这些对象相关slap的信息;详情可以参见内核文档中slapinfo的手册页; /proc/uptime 系统上次启动以来的运行时间,如下所示,其第一个数字表示系统运行时间,第二个数字表示系统空闲时间,单位是秒;

/proc/version 当前系统运行的内核版本号,如下所示;

/proc/zoneinfo 内存区域(zone)的详细信息列表,信息量较大;
如何在/proc目录下创建目录或文件:
要在/proc文件系统中创建一个虚拟文件,请使用proc_create()或proc_create_data()函数。这个函数可以接收一个文件名、一组权限和这个文件在/proc文件系统中出现的位置。这两个函数的返回值是一个proc_dir_entry类型指针(或者为NULL,说明在发生了错误时)。然后就可以使用这个返回的指针来配置这个虚拟文件的其他参数,例如在对该文件执行读操作时应该调用的函数。函数的原型和proc_dir_entry结构中的一部分如下图所示。
创建目录的函数原型如下:
前者不可以传入私有数据,后者可以。关于私有数据的操作,我们后面会使用一个例子来说明。
要从/proc中删除一个文件,可以使用remove_proc_entry()函数。要使用这个函数,我们需要提供文件名字符串,以及这个文件在/proc文件系统中的位置(parent)。函数原型如下:
当在/proc文件系统下创建文件之后用户是怎么访问这个文件的,其实看到proc_create()函数的最后一个参数,传入的是一个file_operations结构体指针,其实,就是通过里面的read和write回调函数来实现的。下面我们来看一个具体的例子。
在/proc目录下创建hello_proc文件,并往里面写入数据或获取里面的数据。
将此文件上传到服务器并编译模块,然后将此模块上传到开发板上面。试验过程如下:
生成的节点如下:

cat /proc/hello_proc的输出信息如下:

echo hello > /proc/hello_proc的输出信息如下:

再次cat /proc/hello_proc的输出信息如下:

在使用proc_create()函数创建文件时,第二个参数是关于权限的设置,我们这里使用默认的0,也就是只有读取权限,这里就不再详细介绍,如果感兴趣可以自己做实验。
