驱动篇:udev 与 devfs(一)
发布日期:2021-06-29 11:35:03 浏览次数:2 分类:技术文章

本文共 2625 字,大约阅读时间需要 8 分钟。

驱动篇:udev 与 devfs(一)

尽管 devfs 有这样和那样的优点,但是,在 Linux 2.6 内核中, devfs 被认为是过时的方法,并最终被抛弃了, udev取代了它。 Linux VFS 内核维护者 Al Viro 指出了几点 udev 取代 devfs 的原因:

1 ) devfs 所做的工作被确信可以在用户态来完成。
2 ) devfs 被加入内核之时,大家期望它的质量可以迎头赶上。
3 )发现 devfs 有一些可修复和无法修复的 bug 。
4 )对于可修复的 bug ,几个月前就已经被修复了,其维护者认为一切良好。
5 )对于后者,在相当长的一段时间内没有改观。
6 ) devfs 的维护者和作者对它感到失望并且已经停止了对代码的维护工作。

udev 完全在用户态工作,利用设备加入或移除时内核所发送的热插拔事件( Hotplug Event )来工作。在热插拔时,设备的详细信息会由内核通过 netlink 套接字发送出来,发出的事情叫 uevent 。 udev 的设备命名策略、权限控制和事件处理都是在用户态下完成的,它利用从内核收到的信息来进行创建设备文件节点等工作。下面给出了从内核通过 netlink 接收热插拔事件并冲刷掉的范例, udev 采用了类似的做法。

netlink 的使用范例:

#include 
static void die(char *s) {
write(2, s, strlen(s)); exit(1); } int main(int argc, char *argv[]){
struct sockaddr_nl nls; struct pollfd pfd; char buf[512]; // Open hotplug event 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(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (pfd.fd == -1)die("Not root\n"); // Listen to netlink socket if (bind(pfd.fd, (void *)&nls, sizeof(struct sockaddr_nl)))die("Bind failed\n"); while (-1 != poll(&pfd, 1, -1)) {
int i, len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT); if (len == -1)die("recv\n"); // Print the data to stdout. i = 0; while (i < len) {
printf("%s\n", buf + i); i += strlen(buf + i) + 1;} } die("poll\n"); // Dear gcc: shut up. return 0;}

编译上述程序并运行,把 Apple Facetime HD Camera USB 摄像头插入 Ubuntu ,该程序会 dump 类似如下的信息:

ACTION=add

DEVLINKS=/dev/input/by-id/usb-Apple_Inc.FaceTime_HD_Camera__Built-in_
CC2B2F0TLSDG6LL0-event-if00 /dev/input/by-path/pci-0000:00:0b.0-usb-0:1:1.0-event
DEVNAME=/dev/input/event6
DEVPATH=/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.0/input/input6/event6
ID_BUS=usb
ID_INPUT=1
ID_INPUT_KEY=1
ID_MODEL=FaceTime_HD_Camera__Built-in_
ID_MODEL_ENC=FaceTime\x20HD\x20Camera\x20\x28Built-in\x29
ID_MODEL_ID=8509
ID_PATH=pci-0000:00:0b.0-usb-0:1:1.0
ID_PATH_TAG=pci-

udev 就是采用这种方式接收 netlink 消息,并根据它的内容和用户设置给 udev 的规则做匹配来进行工作的。这里有一个问题,就是冷插拔的设备怎么办?冷插拔的设备在开机时就存在,在 udev 启动前已经被插入了。对于冷插拔的设备, Linux 内核提供了 sysfs 下面一个 uevent 节点,可以往该节点写一个 “add” ,导致内核重新发送 netlink ,之后 udev 就可以收到冷插拔的 netlink 消息了。我们还是运行上面的代码,并手动往 /sys/module/psmouse/uevent 写一个 “add” ,上述程序会 dump 出来这样的信息:

ACTION=add

DEVPATH=/module/psmouse
SEQNUM=1682
SUBSYSTEM=module
UDEV_LOG=3
USEC_INITIALIZED=220903546792

devfs 与 udev 的另一个显著区别在于:采用 devfs ,当一个并不存在的 /dev 节点被打开的时候, devfs 能自动加载对应的驱动,而 udev 则不这么做。这是因为 udev 的设计者认为 Linux 应该在设备被发现的时候加载驱动模块,而不是当它被访问的时候。 udev 的设计者认为 devfs 所提供的打开 /dev 节点时自动加载驱动的功能对一个配置正确的计算机来说是多余的。系统中所有的设备都应该产生热插拔事件并加载恰当的驱动,而 udev 能注意到这点并且为它创建对应的设备节点。

转载地址:https://blog.csdn.net/zytgg123456/article/details/110388503 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:驱动篇:sysfs 文件系统与 Linux 设备模型
下一篇:驱动篇:驱动的移植(二)(摘录)

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月02日 12时52分31秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

「2020年大学生电子设计竞赛分享」电源题,省一等奖! 2019-04-29
又一国产开源微内核操作系统上线!源代码已开放下载 2019-04-29
10年老兵!从大学毕业生到嵌入式系统工程师的修炼之道…… 2019-04-29
如何才能学好单片机? 2019-04-29
一根网线有这么多“花样”,你知道吗? 2019-04-29
雷军1994年写的诗一样的代码,我把它运行起来了! 2019-04-29
2020年大学生电子设计竞赛,B题,单相在线式不间断电源,详细技术方案! 2019-04-29
大佬终于把鸿蒙OS讲明白了,收藏了! 2019-04-29
C语言指针,这可能是史上最干最全的讲解啦(附代码)!!! 2019-04-29
国内大陆有哪些芯片公司处于世界前10?一起看看! 2019-04-29
单精度、双精度、多精度和混合精度计算的区别是什么? 2019-04-29
中国35位“大国工匠”榜单出炉!西工大、西电合计占半壁江山!清华仅1人!... 2019-04-29
知乎热议:嵌入式开发中C++好用吗? 2019-04-29
2020,Python 已死? 2019-04-29
漫画:程序员相亲?哈哈哈哈哈哈 2019-04-29
30种EMC标准电路分享,再不收藏就晚了! 2019-04-29
这100道Linux常见面试题,看看你会多少? 2019-04-29
十年硬件老司机,结合实际案例,带你探索单片机低功耗设计! 2019-04-29
“2020年嵌入式软件秋招经验和对嵌入式软件未来的一点思考” 2019-04-29
嵌入式的坑在哪方面? 2019-04-29