乌尔里希·丹格尔解释devtmpfs 和 udev 之间的区别很好。
那么sysfs呢?
据我所知,内核使用sysfs将设备节点导出到用户空间以供udev使用。那么 devtmpfs 和 sysfs 是一样的吗?如果是,为什么他们使用不同的名字?如果不是,sysfs 和 devtmpfs 之间的真正区别是什么?
答案1
内核使用sysfs将设备节点导出到用户空间以供udev使用
不。Sysfs 不包含设备节点。 Sysfs主要包含提供设备信息的文件,以及一些允许进程控制设备如何运行的文件。但大多数设备无法通过 sysfs 提供的功能来使用。
我们以硬盘为例。在 下的某处有一个目录/sys/devices
,其路径取决于它如何连接到计算机(例如,/sys/devices/pci0000:00/…
对于连接到控制器的磁盘,该控制器连接到计算机的主 PCI 总线)。在该目录中,您可以找到各种信息,例如其大小、是否可移动、电源状态等。还有分区的子目录。但其中没有任何内容可以提供对磁盘内容的访问。在 中的其他位置/sys
,有指向与该磁盘对应的目录的符号链接: in /sys/block
、 in/sys/class/block
等。但仍然无法访问磁盘的内容。
在 中/dev
,磁盘的条目是一个特殊文件——a块设备。该文件允许进程读取和写入磁盘的内容。 (尽管对于磁盘来说,这种情况通常不会发生;而是安装了磁盘或分区的内容,因此内核正在访问该设备,而进程则不会。)
设备文件允许通过以下方式进行除读写内容之外的一些操作读写控制。可以通过设备文件上的 ioctl 提供 sysfs 提供的所有信息和控制接口。然而,由于以下几个原因,这不太方便:
- 通过 中的单独文件
/sys
,可以细粒度地设置权限。对于每个设备只有一个文件的情况/dev
,要么全有,要么全无。 - 应用程序可以轻松读取和写入单独的文件。您可以只使用
cat
或echo
。使用 ioctl 就困难得多:没有 shell 接口,其他高级语言中通常也没有接口。 - 使用 ioctl,命令必须以数字而不是名称进行编码,并且参数的格式必须在二进制级别定义。使用名称和简单的文本格式可以更轻松地编写软件。
从另一个方向来看,可以通过 sysfs 中的文件提供对设备内容的访问。但这需要在内核中进行额外的工作:sysfs 的设计主要是为了提供小文件和符号链接,并且没有ioctl
现有应用程序所期望的支持。我认为扩展 sysfs 以支持现有设备类型不会有显着的好处,因此设备文件会继续存在。
Sysfs 由内核自动填充,实时反映实际可用的设备。 sysfs 中文件的含义来自其路径,该路径由提供该文件的驱动程序选择。/dev
工作方式不同:文件的含义来自设备文件的类型(块或字符)及其主编号和次编号(这是ls -l
列出的内容,而不是设备的文件大小)。传统上,/dev
是静态的,在系统安装期间创建设备文件;但当设备可以热插拔时,这种方法就不太适用了,因此需要一种/dev
实时反映连接设备的动态。
Linux 经历了动态的多次迭代/dev
。 Linux 2.4 有开发文件系统,其中内核自动创建条目来反映连接的设备。但那是不太好,因为它将设备命名和权限策略硬编码到内核中,所以被userland程序取代乌德夫管理策略,以及/dev
简单的 tmpfs 文件系统(对内核没有特殊意义的内存文件系统)。然后 devfs 部分卷土重来,开发者文件系统,它是 tmpfs 的一个实例,其中可用设备的条目由内核自动创建,但 udev 在此基础上执行它想要的所有管理。
答案2
来自内核文档文件系统文件系统.txt:
sysfs 是一个基于 ram 的文件系统,最初基于 ramfs。它提供了一种将内核数据结构、它们的属性以及它们之间的链接导出到用户空间的方法。
来自一个提交消息到内核源码:
Devtmpfs 允许内核在内核初始化时、注册任何驱动程序核心设备之前创建一个名为 devtmpfs 的 tmpfs 实例。每个具有主要/次要的设备都会在 devtmpfs 中提供一个设备节点。
基本上sysfs
安装/sys
并包含有关设备和设备名称的信息和统计信息。
devtmpfs
已安装/dev
并包含所有设备的特殊设备文件。