sysfs 文件系统

作者:Patrick Mochel 来源:网络 提要 sysfs是2.6内核的一个特性,它允许内核代码经由一个in-memory的文件系统把信息出报(export)到用户进程中,文件系统的目录层级(hierarchy)的组织是严格的,并构成了内核数据结构的内部组织的基础。在这种文件系统中产生的文件大多数是ASCII文件,通常每个文件有一个值。这些特性保证了被出报的信息的准确性并易于被访问,从而使sysfs成为2.6内核的最直观、最有用的特性之一。 介绍 sysfs是内核对象、属性及它们的相互关系的一种表现机制。它提供了两个组件:把这些条目通过sysfs来出报的内核编程接口,和一个用户接口,用来查看和操作这些映射了它们所代表的内核对象的条目。下面这个表揭示了内部(内核)建制与他们的外部(用户空间)sysfs映射。 内部----- 外部 内核对象---目录 对象属性---常规文件 对象关系---符号连接 sysfs 是内核底层的一个核心成分,它的意义在于提供一个较为简单的接口来实施一项简单的任务,代码中很少有过分复杂的内容或含混的描述。然而,像许多底层的核心成分一样,它会有点抽象和疏离以致于难以缕清思路。为了减轻困难,在进入实质性的细节之前本文先对sysfs来一个渐进的诠释。 首先写一段短小精悍的历史描述它的起源,其次是包括了对sysfs的挂载与访问的关键信息,而后传述了sysfs中的目录组织和子系统布局,它为用户理解通过sysfs出报的信息的组织与内容提供了足够的信息,尽管由于时间与篇幅的局限,不是每个对象及其属性都会被写到。 这篇文章的首要目的是为内部sysfs接口 - 用来把内核建制向用户空间出报的数据结构与函数 - 提供一个技术视角,它描述了上面提到的三个概念(内核对象、对象属性和对象关系)中的函数,并为每个概念设一个章节。它还为另外两个用来简化一些普通操作的常规文件接口 - 属性组与二进制属性 - 分别设一个章节。 sysfs是内核空间与用户空间之间的一个信息渠道,用户空间的应用程序有很多机会来利用这种信息,目前的利用法是I/O调度器的参数能力与udev程序。最末章节叙述了使用sysfs的当前应用的一个范例,并且为促使这个领域的进一步开发作一个鞭策。 因为它是个简单的而且基本上是抽象的接口,所以需要很多时间来描述它与使用它的子系统们之间的交互。对于kobject与device model来说更是这样,这两个都是2.6内核的新特性并与sysfs密切地交织在一起,由于篇幅所限本文不可能对这些话题都充分地展开,还是把它们留给其它的文章作主题吧。 1. sysfs 的历史 sysfs是一个in-memory文件系统,最开始是基于ramfs的, ramfs是在2.4.0版内核稳定过程中的时候写成的,它作得很妙,通过它可以看到利用当时还是新事物的VFS layer写一个简单的文件系统是多么地容易,由于它简易并使用VFS,它成为一个好的基础,使其它的in-memory文件系统从它那里衍生出来。 sysfs 最初被称为ddfs(设备驱动文件系统),它的产生是为了调试正在开发过程中的新的驱动模型,调试代码最初使用procfs来出报设备树,但在莱纳斯*托瓦兹的严格的催促下,它转而使用了一个基于ramfs的新的文件系统。 当时,这种新的设备模型被溶入内核(2.5.1前后),为了使其更明了给它换了个名字叫driverfs,次年在2.5版的开发中,这种设备模型与设备文件系统的底层功能证明对其它的子系统很有用。kobject被开发出来,提供了一个中央对象管理机制,而设备文件系统则被转换成sysfs,来表示它的子系统的不可预知性。 2. sysfs 的挂载 sysfs像其它基于内存的文件系统一样可以从用户空间挂载: mount -t sysfs sysfs /sys sysfs还能够在启动时用/etc/fstab文件来自动挂载。大多数支持2.6 内核的发行版都在 /etc/fstab有sysfs行: sysfs /sys sysfs noauto 0 0 注意sysfs被挂载的目录:/sys, 这是sysfs 佳载点的事实标准位置,各主流发行版都采用这个作法。 3.sysfs 的浏览 既然sysfs是由目录、文件、软连接组成的集合,那么就可以用简单的 shell工具来浏览和操作,本人推荐用 tree(1)这个工具,它是内核对象底层的核心的开发过程中最得力的助手。 sysfs挂载点的顶层是一定数量的目录,这些目录代表了注册了sysfs的主要的子系统。在本文撰写之时, 这些目录是: /sys/ | - - block | - - bus | - - class | - - device | - - firmware | - - module | - - power 这些目录是在子系统注册kobject核心的系统启动时刻产生的, 当它们被初始化以后, 它们开始搜寻在各自的目录内注册了的对象。对象注册sysfs的方式以及目录如何产生的将在后文解释. 其间, 有兴趣的话最好在这个sysfs层级中来一番审视, 下面叙述各子系统的含义以及它们的内容。 3.1 块 "块"目录包含了在系统中发现的每个块设备的子目录,每个块设备的目录中是各种属性,描述了方方面面,从设备大小到映射的dev_t数值,有一个指向块设备所映射的物理设备的软连接(在物理设备树上,将在后文说到),还有一个目录揭示了I/O调度器的接口,这个接口提供了一些数据,它们是关于设备请求队列和一些可调整的特性,用户和管理员可以用它们来优化性能,包括用它们来动态改变I/O调度器。每个分区块设备表示为块设备的子目录,这些目录中包含了分区的只读属性。 3.2 总线 "总线"目录包含了在内核中注册而得到支持(统一编译或是通过模块来加载的)的每个物理总线类型的子目录, 部分输出如下: bus/ | - - ide | - - pci | - - scsi | - - usb 每个总线类型以两个子目录列出: devices 和 drivers , devices目录包含了在整个系统中发现的每一个该总线类型的设备的列表,这些列出的设备实际上是在全局设备树中指向设备目录的符号连接。如: | - - 0000:00:00.0 -> ../../../devices/pci0000:00/0000:00:00.0 | - - 0000:00:01.0 -> ../../../devices/pci0000:00/0000:00:01.0 | - - 0000:01:00.0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0 | - - 0000:02:00.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.0 | - - 0000:02:00.1 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.1 | - - 0000:02:01.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:01.0 | - - 0000:02:02.0 -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:02.0 drivers目录包含了注册该总线类型的每个驱动的目录,每个驱动目录中是允许查看和操作设备参数的属性,和指向该设备所绑定的物理设备(在全局设备树上)的软连接。 3.3 类 "类“目录包含了在内核中注册了的每个设备类的表示,一个设备类描述了设备的一个功能类型,如下: class/ | - - graphics | - - input | - - net | - - printer | - - scsi_device | - - sound | - - tty 每个设备类包含了每个分配并注册了那个设备类的类对象的子目录,大多数设备类对象的目录包含了指向与那个类对象关联的设备和驱动目录(分别在全局的设备层级与总线层级)的软连接,注意,在设备与物理设备之间不一定是1:1的映射,一个物理设备也许包含多个类对象执行不同的逻辑功能。例如,一个物理鼠标会映射一个内核鼠标对象,也会映射一个泛”输入事件“设备,也许还会映射一个”输入调试“设备。每个类与类对象会包含各种属性,它们阵列出参数来描述并控制那个类对象,内容与格式完全是类依赖的,并依赖于内核中所存的支持。 (待续)

你可能感兴趣的:(文件系统)