首页 > 系统相关 >Linux设备节点创建方式的演变历史

Linux设备节点创建方式的演变历史

时间:2023-04-20 19:13:05浏览次数:58  
标签:演变 内核 udev devfs https Linux 节点 设备

引子

   遵从"Everything is a file"的思想,在Linux下想要操作设备的话,是需要通过一类叫做设备节点(device node)的特殊文件。设备节点通常位于/dev这个目录下,但是位于其它目录也是可以的。只要翻开一本介绍Linux驱动的书,或者在网上搜索相关的文章,很大概率上会教你在写好驱动代码后,使用mknod这个命令创建设备节点用于测试你的代码。但是作为初学者,肯定会产生一个疑问,Linux系统启动后,/dev目录下就有很多设备,这些设备节点是怎么创建的呢?这时你就会碰到udev或者mdev这样的概念。如果再去看内核代码的话,又会发现好像内核代码也会创建设备节点。
  那么这些方式到底有什么区别和联系,各自存在的原因又是什么呢?实际上,随着Linux内核不断发展,创建设备节点的方式也在变化。这就造成了有些信息混乱。个人就此进行了一些整理和总结,不会涉及到任何代码,只是说明不同时期的设计思路和演变原因,以及加上个人的一些揣测。

远古时期的静态设备节点

   大概在v2.2及之前,Linux的设备号(device number)分为major和minor。最初,major和minor都只占8比特,并且什么设备对应到哪个设备号都是由驱动代码事先申请好的。当操作设备节点时,内核会根据这个设备节点对应的major进行查表操作,以找到相应的驱动。因为那时需要管理的设备还不是很多,所以这种方式并没有很大的问题。但是随着驱动和设备越来越多,这种方法的缺陷也显现出来了。

  • /dev目录下文件太多。因为即使没有相应的设备,也会创建设备节点,存在大量无用节点。此时/dev是位于磁盘上的,占用空间。
  • 设备号不够用了。
  • 设备号冲突。因为只是通过文档来约束驱动实现者选择major。万一两个不同的驱动使用了相同的major,就会存在问题。
  • 根文件系统(root file system)不能是只读的。

不被看好的devfs

  为了解决上面提到的这些问题,Richard Gooch在1998年开始开发devfs,并且在2000年将其合并到了内核主干中。devfs的设计思路包括

  • 直接由驱动创建和管理相应的设备节点。
  • 设备节点文件中不包含设备号,而是直接包含相应的设备操作方法。
  • 设备节点的命名采用树形结构。
  • 只在检测到实际硬件时,才在/dev目录下创建设备节点。

  由于devfs不再使用设备号来索引设备,设备号相关的问题都被解决了。而且设备节点是动态创建的,也解决了/dev目录过大的问题。同时,还提出了一些其它的改进方向,内核可以向用户空间发送设备创建的事件,用户空间可以利用这些事件通知来做一些事情,例如更改设备权限,自动运行脚本来配置复杂设备。
  从设计思想上来讲,devfs应该是先进了许多。虽然devfs的部分使用者反馈不错,但是真正使用了devfs的发行版不是特别多,主要是SGI在推动。devfs没有成主流的可能原因有代码质量不高;对于/dev目录结构改变过大;开发者本身不活跃;没有完全实现最初的设计目标。而且不久之后就出现了另外一种解决方案,也就是下面要提到的udev。因此,devfs最终还是被移除出内核了。

用户空间的udev

  Udev的开发应该是开始于devfs出现了一段时间之后。Udev的开发者不太认同devfs的做法,认为对于设备节点的命名属于策略(policy),不应该位于内核代码中。因此,希望在用户空间来进行设备节点的命名。随着sysfs将设备信息提供给了用户空间,同时/sbin/hotplug提供了设备添加和移除的通知,有可能在用户空间来解决设备节点命名的问题,从而实现/dev目录的动态管理。因此,udev必须配合sysfs来使用。

内核的devtmpfs

  从推广效果来看,udev似乎得到了比devfs更多的支持,并且直接造成了devfs被移除。只是udev也有自己的不足,一个是影响了启动速度,另外一个就是要在用户空间实现udev才能创建设备节点。前面一个问题的原因是,内核在添加和移除设备时都会产生一个uevent,在处理完所有的uevent之后,其它用户态程序几乎不能启动。这两个问题对于嵌入式设备影响都比较大,例如Android就想尽办法不使用udev。
  这里有趣的一点是,作为udev的开发者之一,Greg Kroah-Hartman当时反对devfs的重要理由之一就是设备命名不应该存在于内核中。但是devtmpfs做的实际上也是这件事情,Greg Kroah-Hartman却没有异议。对此,另外一个devtmpfs的开发者Kay Sievers给出的解释是,98%的设备命名策略事实上已经位于内核之中,因此不能成为devtmpfs的反对理由。
  在devtmpfs产生之初,还是有一些疑虑的。不过最终devtmpfs没有步devfs的后尘。现在内核默认配置是启用devtmpfs的。

个人随想

  从以上过程可以看出,Linux对于设备节点的创建方式并不是一成不变的。最开始的mknod/MAKDEV方式,可以看作由用户空间来决定。之后的devfs方式,是由内核代码决定的。而udev方式又变回了用户空间方式来决定。最终现在的devtmpfs加udev则可以看作是内核和用户空间混合的方式,devtmpfs生成基本的设备节点,udev再根据需要修改权限或名称等。
  看了Gooch本人写的devfs介绍,个人认为devfs提出的一些思想实际上和之后的udev,sysfs有一些共通之处。比如层次目录结构就在sysfs中被采用了;而将设备插入拔出事件通知到用户空间则在udev中也体现出来。而且Gooch已经考虑过udev的实现方式来解决问题,也就是内核中产生事件,守护进程处理事件来产生/dev目录。但是他也提到了这种方式相应的缺点。一是需要一个数据库来存储这类事件,而一种自然的实现方式就是文件系统来表现这类事件。二是设备驱动和设备节点之前没有绑定了,需要其它方式来解决。就是sysfs解决了这些问题之后,udev才有可能实现。

参考资料

对于这些概念的其它小结

https://www.binss.me/blog/sysfs-udev-and-Linux-Unified-Device-Model/ 比较全面地提到了devfs,udev和devtmpfs之间的关系,还有一部分代码解释。
http://blog.chinaunix.net/uid-27717694-id-3568856.html 更早的对比devfs和udev的文章。

远古时期的设备创建方法

https://www.linuxjournal.com/article/2597 介绍了/dev目录,以及设备节点的创建方法。
https://www.linuxjournal.com/article/2476 驱动的一般写法。
https://www.linuxjournal.com/article/1219

MAKEDEV相关信息

https://unix.stackexchange.com/questions/396038/why-cant-i-find-makedev-in-the-dev-folder
https://unix.stackexchange.com/questions/356000/why-is-the-name-of-the-makedev-script-spelled-in-all-caps
https://man.openbsd.org/MAKEDEV.8

devfs相关信息

https://www.linuxjournal.com/article/6035 介绍了devfs的一些优点。
https://www.linuxjournal.com/article/4109 关于Linux 2.4的介绍,提及了devfs的优缺点。
https://static.lwn.net/2000/features/OLS/ Ottawa Linux Symposium 2000的总结,提到了没有很多发行版采用devfs。
https://lwn.net/2001/features/OLS/pdf/pdf/devfs.pdf Richard Gooch本人编写的devfs介绍。
https://lwn.net/Articles/15426/ 对于devfs代码质量的简述,大量代码没有被使用。被使用的代码也只局限在小范围。
https://lwn.net/Articles/15425/ 讨论是否要完全移除devfs。

udev

https://www.kernel.org/doc/mirror/ols2003.pdf Ottawa Linux Symposium 2003的总结,其中有Greg Kroah-Hartman写的udev介绍。
https://lwn.net/Articles/28526/ udev 0.1发布,用来代替devfs。
https://lwn.net/Articles/28897/ udev和devfs的初次交锋。
https://lwn.net/Articles/50731/ devfs开始被遗弃。
https://lwn.net/Articles/65197/ Greg Kroah Hartman表示作为udev的开发者,完全不在乎devfs。当初只是为了介绍udev,才选择将它和devfs进行对比,因为很多人熟悉devfs。
https://lwn.net/Articles/139595/ devfs正式被终结。
https://www.linuxjournal.com/article/7496 集合了众多争论udev和devfs的链接。

devtmpfs

https://lwn.net/Articles/330985/ 发布devtmpfs。
https://lwn.net/Articles/331818/ 对于devtmpfs介绍,解答疑虑,说明不是devfs2。

标签:演变,内核,udev,devfs,https,Linux,节点,设备
From: https://www.cnblogs.com/watsondd/p/17337992.html

相关文章

  • CF 580C- Kefa and Park, 1500 / 树的遍历 / 根节点到叶节点的路径上某性质的点不能
    CF580C-KefaandPark这个1500的题这么水?这还不如1200、1300的思维题我开始没考虑周全,这题给出的连边没有讲都是从父节点连向子节点,所有要建双边。#include<iostream>#include<cstring>usingnamespacestd;constintN=1e5+10,M=N*2;typedeflonglon......
  • Linux入门二
    目录一、磁盘管理二、文件挂载1.挂载方法2.挂载示例(1)挂载光盘镜像文件(2)挂载移动硬盘(3)挂载U盘(4)挂载Windows文件共享(5)挂载UNIX系统NFS文件共享(6)补充3.卸载已挂载的设备三、软硬链接四、nfs服务1.什么是NFS2.服务端配置NFS(1)配置(2)共享目录的权限(3)启动nfs服务3.客户端挂载NFS五、......
  • linux 新建服务器基线
    linux新建服务器基线yum-yinstallntpvimnet-toolslsofnctelnetbind-utilspython3python3-develpython3-setuptoolspython3-pippython3-rpm-generatorspython3-libspython3-rpm-macroswgetNTP时钟服务器centos/etc/ntp.conf#注释driftfile/var/lib/ntp/dri......
  • linux下查看服务器的型号
    评:如何看到服务器的型号呢?#dmidecode|grep"Product"ProductName:IBMSystemx3650-[7979R01]-ProductName:SystemPlanarProductName:PowerSuppyBackplaneProductName:PCI-ExpressRiserCard,Slots1&2solaris可以直接用uname-a就能看到服......
  • linux IPtable防火墙 禁止和开放端口
    评:1、关闭所有的INPUTFORWARDOUTPUT只对某些端口开放。下面是命令实现:iptables-PINPUTDROPiptables-PFORWARDDROPiptables-POUTPUTDROP再用命令iptables-L-n查看是否设置好,好看到全部DROP了这样的设置好了,我们只是临时的,重启服务器还是会恢复......
  • linux下安装mysql
    1、查看是否已经安装Mysqlrpm-qa|grepmysql2、上传mysql的安装包到linux下,(.tar.gz版本的)3、解压安装包tar-zxvfmysql-5.7.35-linux-glibc2.12-x86_64.tar.gz4、先检查是否有mysql用户组和mysql用户,没有就添加有就忽略:检查是否有mysql用户组:groupsmysql添加......
  • linux架构day04:ssh远程管理服务实践
    ssh远程管理服务实践linuxssh端口:22加密传输数据支持root用户telnet端口:23明文传输数据不支持root用户windowsrdp端口:3389remotedesttopprotoclssh基本概述SSH是一个安全协议,在进行数据传输时,会对数据包进行加密处理,加密后在进行数据传输。确......
  • Linux系统查看CPU、机器型号、内存等信息-搬运
     Linux系统查看CPU、机器型号、内存等信息原文地址:https://cloud.tencent.com/developer/article/1721406 系统维护时随时可能有需要查看CPU使用率,并根据相应信息分析系统状况的需要。在linux中,可以通过top命令来查看CPU使用状况。关于top命令的详细说明请参看使......
  • 每天一个Linux命令-find.
    find命令主要用于在linux查找出符号条件的文件(也可以包含目录),先在最前面记录一些重点1、find命令后面的多个条件时,默认是与/&/和的逻辑2、只要不指定层数进行find,默认是会一直递归到最后一层的这里笔者列出自己在工作中用到过的一些例子1、从当前目录开始,查找owner是nginx......
  • 龙芯(Loongarch64),在Linux虚拟一个龙芯OS体验下
    前言想体验下龙芯OS,但是又没有龙芯开发板或者龙芯实体机。手头上只有一个X64环境的Linux发行版,应该怎么做呢?概括其实非常简单,可以通过Chroot命令和Qemu在X64的指令集系统上模拟龙芯OS,然后虚拟出一个龙芯的系统,简单的体验下。具体如下:1.首先下载一个CLFS的Lonngarch64System......