UDEV

  1. UDEV的发源及原理概述
  2. udev规则文件
  3. 其他

UDEV的发源及原理概述

udev的出现是用于取代devfs,而devfs被取代有则如下几点其自身不可避免的局限性。

  1. devfs所做的工作被确信可以在应用层完成
  2. 当时devfs有一些可修复和无法修复的bug
  3. 对于可修复的bug,很快就被完成,并不再出现
  4. 而不可修复的bug在相当长的一段时间内没有改观
  5. devfs维护者和作者对其感到失望并停止对其维护

udev完全在用户态工作,利用设备加入或移除时内核所发出的热插拔事件来工作。在热插拔时,设备详细信息会由内核通过netlink套接字发送出来。发送的事件叫uevent。udev的设备命名策略、权限控制和事件处理都是在用户态下完成的,它利用从内核收到的信息来进行设备文件节点的创建工作。

利用netlink接收uevent事件示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int main(int argc, char **argv)
{
int netlink_sock;
struct sockaddr_nl nls;
struct pollfd pfd;
char buf[512];

/* Create netlink socket */
memset(&nls, 0, sizeof (struct sockaddr_nl);
nls.nl_family = AF_NETLINK;
nls.nl_pid = getpid();
nls.nl_groups = -1;

pfd.events = POLLIN;
pfd.fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
if (pfd.fd == -1) {
exit(-1);
}

/* Listen to netlink socket */
if (bind(pfd.fd, (void *)&nls, sizeof(struct sockaddr_nl)))
exit(-1);

while (poll(&pfd, 1, -1) != -1) {
int i, len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT);

if (len == -1){
exit(-1);
}

i = 0;
while (i < len) {
printf("%s\n", buf+i);
i += strlen(buf + i) + 1;
}
}

return 0;
}

当然我们了解了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" 转载请保留原文链接及作者。

目录