udev的实现原理

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

udev实现原理

             

转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd

作者联系方式:李先静<xianjimli at hotmail dot com>

更新时间:2007-4-29

 

相对于linux来说,udev还是一个新事物。然而,尽管它03年才出现,尽管它很低调(J),但它无疑已经成为linux下不可或缺的组件了。udev是什么?它是如何实现的?最近研究Linux设备管理时,花了一些时间去研究udev的实现。

 

udev是什么?u 是指user spacedev是指deviceudev是用户空间的设备驱动程序吗?最初我也这样认为,调试内核空间的程序要比调试用户空间的程序复杂得多,内核空间的程序的BUG所引起的后果也严重得多,device driver是内核空间中所占比较最大的代码,如果把这些device driver中硬件无关的代码,从内核空间移动到用户空间,自然是一个不错的想法。

 

但我的想法并不正确,udev的文档是这样说的,

1.         dynamic replacement for /dev。作为devfs的替代者,传统的devfs不能动态分配majorminor的值,而majorminor非常有限,很快就会用完了。udev能够像DHCP动态分配IP地址一样去动态分配majorminor

 

2.         device naming。提供设备命名持久化的机制。传统设备命名方式不具直观性,像/dev/hda1这样的名字肯定没有boot_disk这样的名字直观。udev能够像DNS解析域名一样去给设备指定一个有意义的名称。

 

3.         API to access info about current system devices 。提供了一组易用的API去操作sysfs,避免重复实现同样的代码,这没有什么好说的。

 

我们知道,用户空间的程序与设备通信的方法,主要有以下几种方式,

1.         通过ioperm获取操作IO端口的权限,然后用inb/inw/ inl/ outb/outw/outl等函数,避开设备驱动程序,直接去操作IO端口。(没有用过)

2.         ioctl函数去操作/dev目录下对应的设备,这是设备驱动程序提供的接口。像键盘、鼠标和触摸屏等输入设备一般都是这样做的。

3.         write/read/mmap去操作/dev目录下对应的设备,这也是设备驱动程序提供的接口。像framebuffer等都是这样做的。

 

上面的方法在大多数情况下,都可以正常工作,但是对于热插拨(hotplug)的设备,比如像U盘,就有点困难了,因为你不知道:什么时候设备插上了,什么时候设备拔掉了。这就是所谓的hotplug问题了。

 

处理hotplug传统的方法是,在内核中执行一个称为hotplug的程序,相关参数通过环境变量传递过来,再由hotplug通知其它关注hotplug事件的应用程序。这样做不但效率低下,而且感觉也不那么优雅。新的方法是采用NETLINK实现的,这是一种特殊类型的socket,专门用于内核空间与用户空间的异步通信。下面的这个简单的例子,可以监听来自内核hotplug的事件。

       
           

#include <stdio.h>

           

#include <stdlib.h>

           

#include <string.h>

           

#include <ctype.h>

           

#include <sys/un.h>

           

#include <sys/ioctl.h>

           

#include <sys/socket.h>

           

#include <linux/types.h>

           

#include <linux/netlink.h>

           

#include <errno.h>

           

 

           

static int init_hotplug_sock(void)

           

{

           

    struct sockaddr_nl snl;

           

    const int buffersize = 16 * 1024 * 1024;

           

    int retval;

           

 

           

    memset(&snl, 0x00, sizeof(struct sockaddr_nl));

           

    snl.nl_family = AF_NETLINK;

           

    snl.nl_pid = getpid();

           

    snl.nl_groups = 1;

           

 

           

    int hotplug_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);

           

    if (hotplug_sock == -1) {

           

        printf("error getting socket: %s", strerror(errno));

           

        return -1;

           

    }

           

 

           

    /* set receive buffersize */

           

    setsockopt(hotplug_sock, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize));

           

 

           

    retval = bind(hotplug_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl));

           

    if (retval < 0) {

           

        printf("bind failed: %s", strerror(errno));

           

        close(hotplug_sock);

           

        hotplug_sock = -1;

           

        return -1;

           

    }

           

 

           

    return hotplug_sock;

           

}

           

 

           

#define UEVENT_BUFFER_SIZE      2048

           

 

           

int main(int argc, char* argv[])

           

{

           

         int hotplug_sock       = init_hotplug_sock();

           

        

           

         while(1)

           

         {

           

                   char buf[UEVENT_BUFFER_SIZE*2] = {0};

           

                   recv(hotplug_sock, &buf, sizeof(buf), 0); 

           

                   printf("%s/n", buf);

           

         }

           

 

           

         return 0;

           

}

           

 

编译:

gcc -g hotplug.c -o hotplug_monitor

 

运行后插/U盘,可以看到:

           

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1

           

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/usbdev2.2_ep00

           

add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0

 

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

猜你喜欢

转载自blog.csdn.net/jggyff/article/details/83691293
今日推荐