2.6 虚拟文件系统
前面几节所介绍的目录和文件,都是真真正正、实实在在的存储在具体的外部
存储设备上的,它们可能是在本机的硬盘、闪存、光盘中,可能保存在不只一个磁
盘分区中,也可能保存在网络中其它主机的存储设备中的。本节所介绍的几个文件
系统,虽然它们出现在根文件系统中,但它里面的内容却无法在任何外部存储设备
中找到,因为它们都在内存中。
2.6.1 proc文件系统
proc是一个重要虚拟文件系统,通过它里面的一些文件,可以获取系统状态信
息并修改某些系统的配置信息。proc文件系统本身不占用磁盘空间,它仅存在于内
存之中,为操作系统本身和应用程序之间的通信提供了一个安全的接口。当我们在
内核中添加了新功能或设备驱动时,经常需要得到一些系统状态的信息,一般这样
的功能可能需要经过一些象ioctl()这样的系统调用来完成。系统调用接口对于一些功
能性的信息可能是适合的,因为应用程序必须将这些信息读出后再做一定的处理。
但对于一些实时性的系统信息,例如内存的使用状况,或者是驱动设备的统计资料
等,我们更需要一个比较简单易用的接口来取得它们。proc文件系统就是这样的一
个接口,我们可以简单的用cat、strings程序来查看这些信息。例如,执行下面的命
令:
#cat /proc/meminfo
你可能会得到如下结果:
MemTotal: 254272 kB
MemFree: 104416 kB
Buffers: 23940 kB
Cached: 103972 kB
SwapCached: 0 kB
Active: 64660 kB
Inactive: 69276 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 254272 kB
LowFree: 104416 kB
SwapTotal: 522072 kB
SwapFree: 522072 kB
Dirty: 48 kB
Writeback: 0 kB
Mapped: 11708 kB
Slab: 11364 kB
CommitLimit: 649208 kB
Committed_AS: 16064 kB
PageTables: 320 kB
VmallocTotal: 770040 kB
VmallocUsed: 7916 kB
VmallocChunk: 760564 kB
HugePages_Total: 0
HugePages_Free: 0
Hugepagesize: 4096 kB
同样的,free、df、top、ps等程序的功能实现,强烈依赖于proc文件系统,为了使用
那些程序,一定要使内核支持proc文件系统,并将其挂接到根文件系统的/proc目录
下。
下表所列的文件或符号连接会出现在/proc目录下,但并不详尽,具体都包含那
些,取决于你的内核配置和具体的硬件设备。
名称 | 功能 |
apm | 高级电源管理信息。 |
buddyinfo | Buddy算法内存分配信息。 |
cmdline | 内核的命令行参数。 |
config.gz | 当前内核的.config文件。 |
cpuinfo | cpu信息 |
devices | 可以用到的设备(块设备/字符设备) |
diskstats | 磁盘I/O统计信息。 |
dma | 使用的DMA通道 |
execdomains | 执行区域列表。 |
fb | Frame buffer信息 |
filesystems | 支持的文件系统 |
interrupts | 中断的使用情况,记录中断产生次数。 |
iomem | I/O内存映射信息 |
ioports | I/O端口分配情况 |
kcore | 内核核心映像,GDB可以利用它查看当前内核的所有数据结构状态。 |
key-users | 密钥保留服务文件 |
kmsg | 内核消息 |
ksyms | 内核符号表 |
loadavg | 负载均衡信息 |
locks | 内核锁 |
mdstat | 磁盘阵列状态 |
meminfo | 内存信息 |
misc | 杂项信息 |
modules | 系统已经加载的模块文本列表 |
mounts | 已挂接的文件系统列表 |
partitions | 磁盘分区信息 |
pci | 内核识别的PCI设备列表 |
self | 访问proc文件系统的进程信息 |
slabinfo | 内核缓存信息 |
splash | splash信息 |
stat | 全面统计状态表 |
swaps | 交换空间使用情况 |
uptime | 系统正常运行时间 |
version | 内核版本 |
vmstat | 虚拟内存统计表 |
zoneinfo | 内存管理区信息 |
表2-6-1
下表所列的目录会出现在/proc目录下,但并不详尽,具体包含那些,取决于你
的内核配置和具体的硬件设备。
名称 | 功能 |
[number] | 进程信息 |
acpi | 高级配置与电源接口 |
asound | ALSA声卡驱动接口 |
bus | 系统中已安装的总线信息 |
dirver | 空目录 |
fs | 空目录 |
ide | IDE设备信息 |
irq | 中断请求设置接口 |
net | 网络各种状态信息 |
scsi | SCSI设备信息 |
sys | 内核配置接口 |
sysvipc | 中断的使用情况,记录中断产生次数。 |
tty | tty驱动信息 |
表2-6-2
proc文件系统的详细内容可以通过执行 man proc命令获得,这里就不再进行更为详
细的介绍了。
2.6.2 sysfs文件系统
与proc文件系统类似,sysfs文件系统也是一个不占有任何磁盘空间的虚拟文件系
统。它通常被挂接在/sys目录下。sysfs文件系统是Linux2.6内核引入的,它把连接在系
统上的设备和总线组织成为一个分级的文件,使得它们可以在用户空间存取。其实
sysfs是从proc和devfs中划分出来的。
/sys目录下会包含下表所列的目录,但并不详尽,不过具体内容还取决于内的配
置和具体的硬件设备。
名称 | 功能 |
block | 块设备 |
bus | 系统总线 |
class | 设备组 |
devices | 系统设备 |
firmware | 固件 |
kernel | 内核 |
module | 内核模块 |
power | 供电系统 |
表2-6-3
讲述sysfs文件系统各目录的详细内容已经超出本文的范围,感兴趣的读者可以查看
有关Linux驱动程序开发的书籍。
2.6.3 devfs文件系统
devfs,也叫设备文件系统(Device Filesystem),设计它的唯一目的就是提供一
个新的(更理性的)方式管理通常位于/dev的所有块设备和字符设备。典型的 /dev
树包含数百个块特殊文件和字符特殊文件,它们全都在根文件系统上。每个特殊文
件都可以让用户空间进程轻松地与内核设备实现交互。举例来说,通过对这些特殊
文件执行操作,你的X服务器就能够访问视频硬件,fsck可以执行文件系统检验,lpd
可以通过并行端口向打印机发送数据。
实际上,通常Linux和Unix更“酷”的方面是,设备不是简单地隐藏在晦涩的
API 之后,而是真正地与普通文件、目录和符号链接一样存在于文件系统上。因为
字符和块设备是映射到普通文件系统名称空间的,我们通常可以用有意义的方式来
与硬件交互,可以仅使用标准 Unix 命令,如 cat 和 dd。除了有趣之外,这还使我
们有更强的能力,并提高生产力。
下表所列的文件或符号连接可能会出现在/dev目录下,但并不详尽,具体内容取
决于你的具体硬件设备。
名称 | 功能 |
audio | 音品设备 |
cdrom[0-9] | cdrom设备,这往往是一个符号连接 |
console | 系统控制台 |
core | 内核镜像,为/proc/kcore的符号连接 |
dmmidi | 固件 |
dsp | 内核 |
dvd | dvd设备,这往往是一个符号连接 |
fb | Frame buffer,一般为/dev/fb0的符号连接 |
fb0 | Frame buffer设备 |
fd | 文件描述符,/proc/self/fd的符号连接 |
fd[0-9]+ | 软盘设备 |
floppy | 软盘设备,一般为fd[0-9]的符号连接 |
full | 满设备,任何写入操作都会失败,并把errno设为ENOSPC,以表示没有剩余空间。 |
fuse | 用户空间的虚拟文件系统 |
hd[a-z][1-9]+ | IDE硬盘 |
sd[a-z][1-9]+ | SCSI或SATA硬盘 |
hpet | HPET设备 |
initctl | 用户与init进程交互的通道。 |
kmem | 存取经过内核虚拟之后的内存 |
kmsg | 任何对该文件的写入都将作为printk的输出 |
log | syslog的本地套接字 |
loop[0-9] | 回环设备,一个磁盘文件模拟一个块设备。 |
lp[0-9] | 打印机 |
md[0-9] | RAID设备 |
mem | 直接存取物理内存 |
midi | MIDI设备 |
mixer | 混音器 |
null | 控设备。任何写入都将直接被丢弃,任何读取都将得到EOF |
parport[0-9] | 并口 |
port | 存取I/O端口 |
ppp | ppp拨号设备 |
psaux | PS/2鼠标 |
ptmx | 所有PTY master的复用器 |
pty[a-z]+[1-9]+ | 伪终端,用于创建ssh等登陆会话 |
ram[0-9]+ | RAM disk,initrd只能使用ram0 |
ramdisk | ram0的符号连接 |
random | 随机数发生器。完全有用户的输入来产生随机数。如果用户停止所有动作,则停止产生随机数。 |
root | 根分区,这是一个到根分区设备的符号连接。 |
rtc | 实时时钟 |
stderr | 标准错误输出,/proc/self/fd/2的符号连接 |
stdin | 标准输入,/proc/self/fd/0的符号连接 |
stdout | 标准输出,/proc/self/fd/1的符号连接 |
tty[1-9,a-z]+ | tty虚拟控制台,tty为当前控制台 |
ttyS[0-9] | 串口 |
urandom | 更快,但是不够安全的随机数发生器。 |
vcs[1-9,a-z]+ | 虚拟控制台的文本内容,一一对应。 |
X0R | /dev/null的符号连接 |
XOR | /dev/null的符号连接 |
zero | 0字节源,可以读取到无限多的0字节。 |
表2-6-4
下表所列的目录可能会出现在/dev目录下,但不是全部,具体情况与你的内核配
置和硬件设备有关。
名称 | 功能 |
cpu | cpu信息 |
disk | 磁盘/光盘信息,里面的内容为具体设备的符号连接 |
input | 设备组 |
mapper | RAID和LVM控制接口 |
net | VMware和Qemu等使用的虚拟网卡 |
pts | devpts文件系统挂载点,用于实现伪终端 |
raw | 裸设备操作 |
shm | Linux独有的tmpfs文件系统挂接点。 |
snd | 声卡控制接口 |
表2-6-5
devfs文件文件系统是内核自动挂接的,当挂接好devfs文件系统后,才能正确执
行init程序。Linux上devfs文件系统与后面讲述的tmpfs文件系统使用相同结构。
2.6.4 tmpfs文件系统
tmpfs文件系统是Linux特有的文件系统,唯一的标准挂接点是/dev/shm。当然,用
户可以将其挂接在其他地方。
tmpfs有些像虚拟磁盘(ramdisk),但不是一回事。说其像虚拟磁盘,是因为它
可以使用你的RAM,但它也可以使用你的交换分区。传统的虚拟磁盘是一个块设
备,而且需要一个mkfs之类的命令格式化它才能使用。tmpfs是一个独立的文件系
统,不是块设备,只要挂接,立即就可以使用。
tmpfs的大下是不确定的,它最初只有很小的空间,但随着文件的复制和创建,
它的大小就会不断变化,换句话说,它会根据你的实际需要而改变大小;tmpfs的速
度非常惊人,毕竟它是驻留在RAM中的,即使用了交换分区,性能仍然非常卓越;
由于tmpfs是驻留在RAM的,因此它的内容是不持久的,断电后,tmpfs的内容就消失
了,这也是被称作tmpfs的根本原因。
有效的使用tmpfs可以极大的提高应用程序或整个系统的性能。有关tmpfs的详细
内容,还请读者参阅其他相关著作,毕竟本文讲述的是一个Linux发行版的开发。
2.6.5 usbdevfs文件系统
顾名思义,usbdevfs就是USB设备文件系统,它是一个动态生成的文件系统,有
些类似于proc文件系统。它的标准挂接点是/proc/bus/usb,当然,也可以挂接到其他
地方。它主要用于:用户级驱动、即插即用、提供USB设备信息、应用程序轮询
USB设备的变化等。
2.6.6 devpts文件系统
devpts文件系统为伪终端提供了一个标准接口,它的标准挂接点是/dev/pts。只要
pty的主复合设备/dev/ptmx被打开,就会在/dev/pts下动态的创建一个新的pty设备文
件。挂接时,UID、GID及其工作模式会指定给devpts文件系统的所有pty文件。这可
以保证伪终端的安全性。
讨论devpts文件系统的详细内容,已经超过本文范围,还请读者参考其他专
著。
2.7 结束语
贯穿Linux的整个文件组织结构,无不洋溢着那继承自Unix的深厚的文化底蕴,
美不胜收。使我不得不感叹,Linux是多么伟大的一个操作系统。正是由于这些,
Linux才长久不衰,越发显得青春洋溢,让我们这些热爱Linux的人为其流连忘返。
到了这里,对于Linux的文件组织结构,我相信各位读者应该有了感官上的认识
了,我也再次感谢你,为了Magic Linux,能够坚持将这些丑陋的文字读到这里。在
下一章里,我将讲述如何利用本章与上一章的知识,来构建一个能够工作的基本系
统。
(未完...待续...)