linux下热插拔事件的产生是怎样通知到用户空间,kobject_uevent_env之uevent

1.kobject, ktype, kset

   1) kobject: 代表sysfs中的目录。

   2) ktype: 代表kobject的类型,主要包含release函数和attr的读写函数。比如,所有的bus都有同一个bus_type;所有的class都有同一个class_type。  

   3) kset: 包含了subsystem概念,kset本身也是一个kobject,所以里面包含了一个kobject对象。另外,kset中包含kset_uevent_ops,里面主要定义了三个函数

       int (*filter)(struct kset *kset, struct kobject *kobj);

       const char *(*name)(struct kset *kset, struct kobject *kobj);

       int (*uevent)(struct kset *kset, struct kobject *kobj, struct kobj_uevent_env *env);

这三个函数都与uevent相关。filter用于判断uevent是否要发出去。name用于得到subsystem的名字。uevent用于填充env变量。

2.uevent内核部分


       uevent是sysfs向用户空间发出的消息。比如,device_add函数中,会调用kobject_uevent(&dev->kobj, KOBJ_ADD); 这里kobj是发消息的kobj,KOBJ_ADD是发出的事件。uevent的事件在kobject_action中定义:

enum kobject_action {

       KOBJ_ADD,

       KOBJ_REMOVE,

       KOBJ_CHANGE,

       KOBJ_MOVE,

       KOBJ_ONLINE,

       KOBJ_OFFLINE,

       KOBJ_MAX

};

 

int kobject_uevent(struct kobject *kobj, enum kobject_action action)

{

       return kobject_uevent_env(kobj, action, NULL);

}

 

  • kobject_uevent_env:

       由kobject的parent向上查找,直到找到一个kobject包含kset。

       如果kset中有filter函数,调用filter函数,看看是否需要过滤uevent消息。

       如果kset中有name函数,调用name函数得到subsystem的名字;否则,subsystem的名字是kset中kobject的名字。

       分配一个kobj_uevent_env,并开始填充env环境变量:

       增加环境变量ACTION=<action name>

       增加环境变量DEVPATH=<kobj’s path>

       增加环境变量SUBSYSTEM=<subsystem name>

       增加环境变量kobject_uevent_env中参数envp_ext指定的环境变量。

       调用kset的uevent函数,这个函数会继续填充环境变量。

       增加环境变量SEQNUM=<seq>,这里seq是静态变量,每次累加。

       调用netlink发送uevent消息。

       调用uevent_helper,最终转换成对用户空间sbin/mdev的调用。

3.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中。

 

4.uevent在设备驱动模型中的应用


在sys目录下有一个子目录devices,代表一个kset。

创建设备时,调用的device_initialize函数中,默认会把kset设置成devices_kset,即devices子目录代表的kset。

devices_kset中设置了uevent操作集device_uevent_ops。

static struct kset_uevent_ops device_uevent_ops = {

       .filter =    dev_uevent_filter,

       .name =   dev_uevent_name,

       .uevent = dev_uevent,

};

 

dev_uevent_filter中,主要是规定了要想发送uevent,dev必须有class或者bus。

dev_uevent_name中,返回dev的class或者bus的名字。

dev_uevent函数:

       如果dev有设备号,添加环境变量MAJOR与MINOR。

       如果dev->type有值,设置DEVTYPE=<dev->type->name>。

       如果dev->driver,设置DRIVER=<dev->driver->name>。

       如果有bus,调用bus的uevent函数。

       如果有class,调用class的uevent函数。

如果有dev->type,调用dev->type->uevent函数。

 

一般在bus的uevent函数中,都会添加MODALIAS环境变量,设置成dev的名字。这样,uevent传到用户空间后,就可以通过对MODALIAS的匹配自动加载模块。这样的bus例子有platform和I2C等等。

 转自:http://blog.csdn.net/bingqingsuimeng/article/details/7924473

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: kobject_uevent_env是一个内核函数,用于发送内核事件通知。它可以在内核中创建一个kobject对象,并将其与一个事件关联起来,然后将事件发送到用户空间。这个函数可以用于驱动程序中,以通知用户空间有关设备状态的变化。 ### 回答2: kobject_uevent_env是一个内核级别的函数,用于通知用户空间的udev守护进程设备的状态变化。在Linux内核中,每个设备都被抽象成一个kobject结构体。当设备的状态发生改变(如插入或移除设备),内核调用kobject_uevent_env函数生成一个事件消息,该消息包含了设备发生变化的相关信息。这个事件消息将被传递给udev守护进程,从而触发相应的设备操作。 kobject_uevent_env函数的原型如下: ``` int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, char **envp); ``` 其中: - kobj:要发送事件消息的设备的kobject结构体。 - action:设备发生的操作,如添加(KOBJ_ADD)或删除(KOBJ_REMOVE)。 - envp:指向要发送给udev的事件消息的缓冲区指针。 kobject_uevent_env函数也支持环境变量的传递。在发送事件消息时,可以将一些自定义的环境变量随消息一起传递给udev守护进程,以便udev能够根据这些环境变量执行相应的操作。 通常来说,kobject_uevent_env函数是由内核模块中的设备驱动程序所调用的。设备驱动程序在操作设备时,会调用kobject_uevent_env函数向用户空间的udev守护进程发送事件消息,通知它设备的状态变化。在用户空间,udev守护进程将根据这些事件消息执行相应的设备管理操作。 ### 回答3: kobject_uevent_env 是一个内核函数,它用于通知用户空间有关内核对象的事件通知是通过用户空间的 uevent 机制实现的,这个机制允许内核将事件通知用户空间的程序中。kobject_uevent_env 函数将事件的环境信息作为参数传递给 uevent 机制,所以用户空间程序可以根据环境信息来处理事件。 kobject_uevent_env 函数的参数是一个指向 kobject 结构体的指针和一个环境变量数组。kobject 结构体表示内核对象,环境变量数组包含事件相关的环境变量。环境变量数组的每个元素都是一个字符串,格式为 "key=value"。其中,key 表示环境变量的名称,value 表示环境变量的值。 kobject_uevent_env 函数的调用者通常是内核驱动程序,当驱动程序中的某个内核对象发生事件时,驱动程序会调用 kobject_uevent_env 函数来通知用户空间用户空间程序可以使用 libudev 库来监视 uevent 事件并相应地处理。 总之,kobject_uevent_env 是内核中实现 uevent 机制的重要函数之一,它允许内核将事件通知用户空间,并传递事件相关的环境信息。通过 uevent 机制,用户空间程序可以监视内核对象的事件并做出相应的处理,这对于管理设备和驱动程序非常重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值