Chinaunix首页 | 论坛 | 博客
  • 博客访问: 494750
  • 博文数量: 135
  • 博客积分: 3010
  • 博客等级: 中校
  • 技术积分: 905
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-24 19:31
文章分类

全部博文(135)

文章存档

2010年(135)

我的朋友

分类: LINUX

2010-08-17 14:59:04

   Udevd如何获取内核的这些模块动态变化的信息
设备节点的创建,是通过sysfs接口分析dev文档取得设备节点号,这个很显而易见。那么udevd是通过什么机制来得知内核里模块的变化情况,如何得知设备的插入移除情况呢?当然是通过hotplug机制了,那hotplug又是怎么实现的?或说内核是如何通知用户空间一个事件的发生的呢?
答案是通过netlink socket通讯,在内核和用户空间之间传递信息。
内核调用kobject_uevent函数发送netlink message给用户空间,这部分工作通常无需驱动去自己处理,在统一设备模型里面,在子系统这一层面,已将这部分代码处理好了,包括在设备对应的特定的Kobject创建和移除的时候都会发送相应addremove消息,当然前提是您在内核中配置了hotplug的支持。
Netlink socket
作为一种内核和用户空间的通信方式,不但仅用在hotplug机制中,同样还应用在其他很多真正和网络相关的内核子系统中。
Udevd
通过标准的socket机制,创建socket连接来获取内核广播的uevent事件 并解析这些uevent事件。

4.2        Udevd如何监控规则文档的变更
假如内核版本足够新的话,在规则文档发生变化的时候,udev也能够自动的重新应用这些规则,这得益于内核的inotify机制, inotify是一种文档系统的变化通知机制,如文档增加、删除等事件能够立即让用户态得知。
udevd中,对inotifyudevnetlink socket文档描述符都进行了select的等待操作。有事件发生以后再进一步处理。

4.3        Udevtrigger的工作机制?
运行udevd以后,使用udevtrigger的时候,会把内核中已存在的设备的节点创建出来,那么他是怎么做到这一点的?分析udevtrigger的代码能够看出:
udevtrigger
通过向/sysfs 文档系统下现有设备的uevent节点写"add"字符串,从而触发uevent事件,使得udevd能够接收到这些事件,并创建buildin的设备驱动的设备节点连同任何已insmod的模块的设备节点。
所以,我们也能够手工用命令行来模拟这一过程:
/ # echo "add" > /sys/block/mtdblock2/uevent
/ # 
/ # UEVENT[178.415520] add      /block/mtdblock2 (block)
但是,进一步看代码,您会发现,实际上,不管您往uevent里面写什么,都会触发add事件,这个从kernel内部对uevent属性的实现函数能够看出来,默认的实现是:
static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
                         const char *buf, size_t count)
{
       kobject_uevent(&dev->kobj, KOBJ_ADD);
       return count;
}
所以不管写的内容是什么,都是触发add操作,真遗憾,我还想通过这个属性实验remove的操作。 不知道这样限制的原因是什么。
udevstart的实现方式和udevtrigger就不同了,他基本上是重复实现了udevd里面的机制,通过遍历sysfs,自己完成设备节点的创建,不通过udevd来完成。

4.4        其他
      udevd
创建每一个节点的时候,都会fork出一个新的进程来单独完成这个节点的创建工作。
      Uevent_seqnum 
用来标识当前的uevent事件的序号(已产生了多少uevent事件),您能够通过如下操作来查看:
$ cat /sys/kernel/uevent_seqnum
2673

阅读(2156) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~