UDEV
UDEV的发源及原理概述
udev的出现是用于取代devfs,而devfs被取代有则如下几点其自身不可避免的局限性。
- devfs所做的工作被确信可以在应用层完成
- 当时devfs有一些可修复和无法修复的bug
- 对于可修复的bug,很快就被完成,并不再出现
- 而不可修复的bug在相当长的一段时间内没有改观
- devfs维护者和作者对其感到失望并停止对其维护
udev完全在用户态工作,利用设备加入或移除时内核所发出的热插拔事件来工作。在热插拔时,设备详细信息会由内核通过netlink套接字发送出来。发送的事件叫uevent。udev的设备命名策略、权限控制和事件处理都是在用户态下完成的,它利用从内核收到的信息来进行设备文件节点的创建工作。
利用netlink接收uevent事件示例如下:
1 | int main(int argc, char **argv) |
当然我们了解了udev可以通过热插拔事件来创建对应的设备文件,但对于冷插拔设备来说在开机前就已经存在了,在udev启动前就已经插入了。因此对于这类设备来说,在udev启动后,在其对应的sysfs下面存在一个uevent节点,向该节点写入“add”,就会导致内核重新发送netlink。
udev规则文件
udev规则文件以行为单位,’#’开头的行为注释行,其余每行代表一条规则。
规则由两部分组成:匹配部分和赋值部分组成。都分别具有其对应的关键字。匹配关键字包括:ACTION(行为),KERNEL(匹配内核设备名),BUS(匹配总线类型),SUBSYSTEM(匹配子系统名),ATTR(匹配属性信息)等。赋值关键字包括:NAME(创建的设备文件名),SYMLINK(创建的符号链接名),OWNER(设置设备的所有者),GROUP(设置设备的组),IMPORT(调用外部程序),MODE(节点访问权限)等。
规则示例1如下:
1 | SUBSYSTEM="net", ACTION="add", DRIVERS="?*", ATTR{address}="08:00:27:35:be:ff", ATTR{dev_id}="0x0", ATTR{type}="1", KERNEL="eth*", NAME="eth1" |
规则解释:
当系统中出现新硬件属于net子系统,系统对该硬件所采取的动作是”add”,这个硬件的address属性等于08:00:27:35:be:ff,dev_id属性等于0x0,type属性等于1,内核中的设备名为eth*时,则创建设备文件/dev/eth1
示例2:
1 | SUBSYSTEM="usb", ATTR{serial}="HXOLL1113382384", NAME="lp_epson", SYMLINK+="printers/epson_stylus" |
规则解释:
一台USB打印机的序列号为HXOLL1113382384时,创建/dev/lp_epson文件,并同时创建一个对应的符号链接/dev/printers/epson_stylus
udev的规则写法灵活,匹配部分可以使用shell通配符。其中‘*’代表任意长度字符,’?’代替一个字符。此外%k就是KERNEL,%n则是设备的KERNEL序号。
其他
“udevadm info -a -p $(udevadm info -q path -n /dev/\<节点名>)”命令可以在知道设备的/dev路径的前提下反向分析设备的/sys路径。
在嵌入式系统中,可以使用udev的轻量级版本mdev。而在android中则没有使用udev,而是使用的vold,其原理与udev是一样的,都是监听NETLINK套接字来动态创建和删除设备。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 yxhlfx@163.com
文章标题:UDEV
本文作者:红尘追风
发布时间:2017-03-15, 21:41:03
原始链接:http://www.micernel.com/2017/03/15/udev/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。