udev——设备文件管理的用户空间实现

自2.5版内核起,用户空间的进程可以通过sysfs文件系统访问按层次组织的所有系统的外部设备(包括物理设备和虚拟设备)的元信息 。另外,“/sbin/” 会在系统设备热插拔时向用户空间发出提示 。具备了这两项功能后,在用户空间内动态管理设备文件(/dev目录)成为现实,一直需求的更灵活的设备名分配策略成为现实 。
本报告文分析udev,一支代替devfs——只是实现动态管理/dev目录条目的方案——的用户空间程序,解决由devfs不能单独解决的一些问题:
本文将解释为什么在用户空间实现的udev会优于在内核实现的devfs,并且详述在实现udev上的一些设计考虑 。另外,这里也讲解udve的工作原理和怎样给udev制作插件(如命名方案 ),还有一些udev使用上需要考虑的事情 。
1.
/dev目录挂接了所有系统设备的设备文件,用户程序通过这些文件调用设备的驱动程序,从而使用设备 。例如,/dev/hda 是系统第一个IDE磁盘的设备文件,/dev/hda 被绑定了一主设备号和次设备号,内核根据主设备号找到IDE磁盘的驱动程序 。目前,/dev下的很多文件名(和相应的设备号)已经被分配,分配任务由 The LinuxNames And( their web site at )负责 。
当Linux支持一种新设备类型时,它必须被分配一个主设备号和数个次设备号 。在2.4版及以前,可用的主设备号和次设备号都只是8位(1-255) 。由于设备号有限,在2.3版的开发期设备号已经告急 。2.6版起,主设备号提升为12位,次设备号20位 。
2.前sysfs的问题 2.1 设备与设备文件的映射不固定
当内核发现一支已知类型的新硬件时,它一般会按顺序为这新硬件分配硬件所属类型的主设备号和次设备号 。例如,在.txt分配中,USB设备号是180,USB打印机的设备号是0-15;当系统启动时,第一支被发现的USB打印机会分配(180,0),设备名是/dev/usb/lp0;第二支被发现的USB打印机会分配(180,1),设备名是/dev/usb/lp1 。当用户改动USB的拓扑结构,例如添加一个USB hub,那么上述的USB打印机的检测次序有可能改变,也就是说次设备号有可能交换 。在sysfs出现以前,这种变动,用户程序很难发现 。
同样的情况出现在具有热插拔功能的总线设备上——PCI、、 USB和 。
有了sysfs文件系统,用户程序想知道物理设备被分配了哪个次设备号变得容易 。像上面的系统有两支不同的USB打印机的情况,/sys/class/usb的目录树结构像下面的:
在/sys下总是有某一设备的物理信息,例如生产厂商和序列号,而这些信息可以通过一个具有丰富语义的层次目录内找到 。例如次设备号为0 的USB打印机在/sys/class/usb/lp0/内 。由上图可知设备文件/dev/usb/lp0所关联的设备是序列号为的USB打印机,而设备文件/dev/usb/lp1所关联的设备是序列号尾号330的USB打印机 。
sysfs现在可以让用户查对哪个设备关联了哪个设备文件了 。如果设备关联变动,那么设备重配置可以在用户空间进行,不必麻烦内核[注] 。
注:虽然如此,普通用户一般并不关心/dev/usb/lp0 和 /dev/usb/lp1是否变动过,他们只想原封不动使用原有功能,不想做任何的配置工作,哪怕在用户空间 。
2.2 没有足够的设备号
前sysfs的设备号分配是静态的 。设备名和设备号的静态分配管理方案中,设备号由16位提升到32位暂缓了设备号短缺的问题,但是也保不齐有一天也不够用;而且静态管理方案还需要一个额外的名字授权管理 。如果将管理方法改用动态方式,那么设备名与设备号只有单机冲突问题,没有社区冲突问题,这样名字授权管理可以省去,设备号也不可能用完 。但是,要实现动态分配的最大问题是,用户空间无法知道设备的设备号(包括主设备和次设备号) 。