免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 804 | 回复: 0
打印 上一主题 下一主题

Udev研究之与模块关系 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-12 11:11 |只看该作者 |倒序浏览
Udev研究之与模块关系
    最近在做CLFS,又遇到了Udev的问题.自己对udev和模块之间加载和被加载,依靠和被依靠的关系一直有点不清楚,这次遇到了就索性搞明白.


    作者: Manson.Li
    更新日期:2007-9-12
    联系方式:
lizhilianglove@163.com

    转载请注明作者和出处.
   
   
    本文主要解决的问题是:
1.     udev创建设备文件需要事先有设备驱动,而Linux内核默认在打开设备文件的时候加载驱动?那么这个先有鸡还是先有鸡蛋的问题是如何解决的?
2.     udev在设计上不是应用在打开设备时候加载设备驱动的,可是start_udev这个tools却能在系统启动的时候加载已经有的设备的驱动并创建其设备文件,其中的原理是?

关于udev的其他一些知识比如说具体应用,rule编写,这里介绍一些网站:
Udev的主网站(英文):
   
http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html
对应的中文翻译:
    FQA: 王旭 http://gnawux.blogchina.com
    Primer:
http://hi.baidu.com/chenzhuoyou/blog/item/fb2f4708bc27e7970a7b8237.html
      
panjet
写的udev介绍: udev轻松上路
        
www.linuxforum.net/forum
>>
Linux 高级应用
  >>
Linux 嵌入技术

1.    一些准备知识
1.1  Sysfs
    Sysfs是如何知道当前系统中的设备以及对应的设备号的呢? Sysfs发现设备是通过kernel启动时候系统初始化进行设备枚举发现的,而对应的设备号就是由对应的驱动注册的,这些驱动即可以是包含在内核里的也可以是模块的.在驱动没有加载前,系统是能通过VID和POD(Vendor ID/ Product ID)认识设备,但是不能驱动设备的.
    现在udevd(守护进程)就能使用驱动注册的设备号信息来创建设备文件了.

1.2  Udev Bootscript
    CLFS中提供是s10udev这个 initscript来在Linux启动的时候创建设备.在我看来和start_udev这个tools工具是一样的,这个工具本身也就是一个shell script.
    首先取消掉默认的uneven handler: /sbin/hotplug,因为kernel不再需要这个hotplug了,udevd将通过netlink socket开监听uevents.然后将在/dev中创建一些静态的设备文件节点,因为这些设备有些不被udev支持,有些又是运行udev的必然前提.(这边要区别开为内核能正常启动而创建的null和console,目的不同)

1.3  Device Node Create
    这边具体讲解udevd是如何通过sys来获得设备的大小设备号的.首先udev在sys中寻找到大小设备号,必然/sys/class/tty/vcs/dev中有”7:0”便是了.根据这个号再到/etc/rules.d中寻找创建规则进行创建.

2.    udev和module之间的关系
2.1  Module Loading
    被编译成模块的设备驱动可能会有一个基于bus-specific identifier的别名,这个别名就指明了其支持的设备.可以通过modinfo看到.比如 snd-fm801驱动支持Vendor ID 0x1319,device ID 0x0801的PCI设备,那么它的别名就是“pci:v00001319d00000801sv*sd*bc04sc01i*”对应大多数设备又可以从sys中找到与这个别名对应的标识. 比如/sys/bus/pci/devices/0000:00:0d.0/modalias中就包含了这样的字符串“pci:v00001319d00000801sv00001319sd00001319bc04sc01i00”,这样就在设备和驱动之建立了联系.
    所以udevd便调用/sbin/midprobe使用上面的这些别名来加载设备的驱动.

    好,现在来回答我们的第二个问题: start_udev这个tools是如何在系统启动时候加载设备驱动的?
   
    补充一下:这里指的start_udev和udevstart都是用在fedora下的两个tools, start_udev实质上就是调用udevstart.如果从tarball编译udev是没有这两个的,取而代之的是: 一个udev脚本, 一个udevtrigger(这个作用和udevstart相同).

    在fedora系统中,start_udev将会被在rc.sysinit前调用,也就是kernel执行完后第一程式.这个时候内存中的驱动只有包含在内核中的或者通过initrd方式加载的. 依然有许多设备虽然系统已经识别到,但是并没有加载驱动. 在这些系统识别到的设备我们就能在/sys下找到对应的设备目录,目录中有一个uevent的文件,其实也就是系统识别到设备时候发出的event事件.
    由于在start_udev之前,系统中并没有处理uevents的handler,所以设备对应的模块并没有被加载.
    Start_udev开始后首先做的是同1.2 udev bootscript同样的事情.然后其便开始遍历/sys目录,寻找并试图打开uevent文件.(找到并能打开这个文件就代表有这个设备存在),如果寻找到就往里面写入”add”,相当于再次触发event事件. 但是这个时候udevd守护进程已经开启,它捕捉到了这个事件,便通过/sys下的modalias获得驱动对应模块的别名,然后调用modprobe加载.

2.2  udev处理热插拔/动态设备   
    当你插入一个设备比如说USB Disk,内核发现设备连接并产生一个uevent,这个uevent被udevd捕获并按照上述的方法处理.

3.    不适合上述方法的模块加载情形
    Udev只能加载那些有 bus-specific别名,并且bus驱动将必要的设备别名正确的写在sysfs的modalias里面的设备模块.对于其他情况的情况就要用其他方法了. 这样检查一个模块是否被udev支持也就是通过modinfo看模块的命名并在/sys/bus寻找modalias文件.
   
    那么对于不适合上述条件的module,对于”wrapper”形式的可以通过修改/etc/modprobe.conf 添加“install module_1 /sbin/modprobe module_2”也就是在安装module_1的时候自动安装module_2. 当然不是”wrapper”形式的,就通过修改开机脚本,手动添加了.(” wrapper”意思就是说module_1是作为module_2的补充,本身并没有什么意义)

    现在回到第一个问题: udev创建设备文件需要事先有设备驱动,而Linux内核默认在打开设备文件的时候加载驱动?那么这个先有鸡还是先有鸡蛋的问题是如何解决的?
    Udev创建设备名前是需要驱动的,那么那些符合udev自动加载的模块(实质上是udev调用modprobe)在udevstart中便自动加载好了驱动. 当然其他的设备,如果你在udev创建设备前,没有手动的加载的话,那么是自然不能创建设备文件的了.


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/43031/showart_380128.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP