Chinaunix首页 | 论坛 | 博客
  • 博客访问: 622152
  • 博文数量: 168
  • 博客积分: 1053
  • 博客等级: 少尉
  • 技术积分: 1187
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-30 17:20
个人简介

公众号【嵌入式er笔记】持续记录和分享C/C++、Linux、ARM、Android、IoT等技术相关知识,以及职场、生活经验和感悟。

文章分类

全部博文(168)

分类: LINUX

2015-02-14 12:13:58

原文地址:笔记之-uevent机制 作者:djking1986

uevent机制
==========
 
简单的梳理一下框架,清晰自己的思路。
 
uevent, user space event. 内核与用户空间的一种通信机制,基于netlink机制,主要用于设备驱动模型,例如热插拔。
 
也就是说在某个时刻触发某个事件并通知给用户空间。
 
事件:
enum kobject_action {
 KOBJ_ADD,
 KOBJ_REMOVE,
 KOBJ_CHANGE,
 KOBJ_MOVE,
 KOBJ_ONLINE,
 KOBJ_OFFLINE,
 KOBJ_MAX
};
 
触发点:
 
kobject_uevent()
 
如device_add()中的触发:
kobject_uevent(&dev->kobj, KOBJ_ADD);
 
在kobject_uevent()中会先执行集成在kset中的kset_uevent_ops, 之后再通过netlink传递给用户空间。
 
struct kset_uevent_ops {
 int (* const filter)(struct kset *kset, struct kobject *kobj);
 const char *(* const name)(struct kset *kset, struct kobject *kobj);
 int (* const uevent)(struct kset *kset, struct kobject *kobj,
        struct kobj_uevent_env *env);
};
 
filter用于判断uevent是否要发出去,name用于得到subsystem的名字,uevent用于填充env变量。
 
我们可以看到kobject_uevent()中的代码:
 
 if (uevent_ops && uevent_ops->filter)
  if (!uevent_ops->filter(kset, kobj)) {
       ......
  }
 /* originating subsystem */
 if (uevent_ops && uevent_ops->name) {
  subsystem = uevent_ops->name(kset, kobj);
  ......
 }
 
  ......
 
 /* let the kset specific function add its stuff */
 if (uevent_ops && uevent_ops->uevent) {
  retval = uevent_ops->uevent(kset, kobj, env);
    ......
 }
 
最后调用netlink接口发送出去,用户层会根据所设置的env变量来启动相应操作,至于env变量设置内容我不作深究。
 
以上就是内核中uevent机制的简述。
-----------------------------------------------------------------------------------------------------
 
下面就简单提一下应用层的一些机制(注:以下我并没有详细去分析,而是抄录某位大虾的原创):
 
uevent的用户空间程序有两个,一个是udev,一个是mdev。
 
udev通过netlink监听uevent消息,它能完成两个功能:
       1.自动加载模块
       2.根据uevent消息在dev目录下添加、删除设备节点。
另一个是mdev,mdev在busybox的代码包中能找到,它通过上节提到的uevent_helper函数被调用。
udev的模块自动加载过程:
 
etc目录下有一个uevent规则文件/etc/udev/rules.d/50-udev.rules
udev程序收到uevent消息后,在这个规则文件里匹配,如果匹配成功,则执行这个匹配定义的shell命令。
例如,规则文件里有这么一行:
ACTION=="add", SUBSYSTEM=="?*", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}"
所以,当收到uevent的add事件后,shell能自动加载在MODALIAS中定义的模块。

mdev的模块自动加载过程与之类似,它的配置文件在/etc/mdev.conf中。例如:
$MODALIAS=.* 0:0 660 @modprobe "$MODALIAS"
这条规则指的是:当收到的环境变量中含有MODALIAS,那么加载MODALIAS代表的模块。
mdev的详细说明在busybox的docs/mdev.txt中。
阅读(1959) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~