udev比devfs好在哪里

udev比devfs好在哪里

为什么devfs 会被udev取代?
首先明确一点
udev 运行在用户空间 (内核版本2.6及以上)
devfs 运行在内核空间(内核版本 2.4)

Linux 设计中强调的一个基本观点是机制策略的分离。
机制是做某样事情的固定步骤、方法,而策略就是每个步骤所采取的不同方式。
机制是相对固定的,而每个步骤采用的策略是不固定的。
机制是稳定的,而策略则是灵活的,因此在linux内核中,不应该实现策略

比如Linux 提供API可以让人把县城优先级调高或者调低,或者调整调度策略为SCHED_FIFO,
但是Linux内核本身却不管谁高谁低。

提供API属于机制,谁高谁低属于策略,所以应该是应该程序自己去告诉内核要高或者低,而内核不管这些杂事。
因此属于策略的东西应该被移动用户空间中,谁爱给那个设备创建什么名字或者想做更多的处理,谁自己去设定。
内核只管把这些信息告诉用户就可以了。

这就是位于内核空间的devfs应该被位于用户空间的udev取代的原因

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

devfs 与 udev 的另一个显著区别在于:采用devfs,当一个并不存在的/dev节点被打开的时候,devfs能自动加载对应的驱动,而udev则不这么做。这是因为udev的设计者认为Linux应该在设备被发现的时候加载驱动模块,而不是当它被访问的时候。

udev的设计者认为devfs所提供的打开/dev节点时自动加载驱动的功能对一个配置正确的计算机来说是多余的。系统中所有的设备都应该产生热插拔事件并加载恰当的驱动,而udev能注意这点并且为它创建对应的设备节点

本代码就是从内核通过netlink接收热插拔事件并显示出来

#include <linux/netlink.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <poll.h>
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;
}

上文摘抄自《Linux设备驱动开发详解:基于最新的Linux 4.0内核》

Makefile文件

# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
SRC = main.c
OBJ = main



all:
	$(CROSS_COMPILE)gcc   $(SRC)   -o $(OBJ) 
clean:
	rm  $(OBJ)  $(OBJ).o

手动触发uevent
echo add > /sys/module/psmouse
此时就能看到信息流被打印出来了

如果提示没有权限这样操作,可以用一个U盘插入电脑,也能看到内核发出的netlink 信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

white_line

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值