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

转自:http://blog.csdn.net/myarrow/article/details/8259888

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

时间: 2024-09-26 11:58:28

linux下热插拔事件的产生是怎样通知到用户空间,kobject_uevent_env之uevent【转】的相关文章

linux下使用 du查看某个文件或目录占用磁盘空间的大小

du -ah --max-depth=1 这个是我想要的结果 a表示显示目录下所有的文件和文件夹(不含子目录),h表示以人类能看懂的方式,max-depth表示目录的深度. du命令用来查看目录或文件所占用磁盘空间的大小.常用选项组合为:du -sh 一.du的功能:`du` reports the amount of disk space used by the specified files and for each subdirectory (of directory arguments)

Linux下套接字详解(十)---epoll模式下的IO多路复用服务器

epoll模型简介 epoll可是当前在Linux下开发大规模并发网络程序的热门人选,epoll 在Linux2.6内核中正式引入,和select相似,其实都I/O多路复用技术而已,并没有什么神秘的. 其实在Linux下设计并发网络程序,向来不缺少方法,比如典型的Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模型和poll模型,那为何还要再引入Epoll这个东东呢?那还是有得说说的- 常用模型

U盘在Linux下不得不知的操作技巧

  技巧一: Linux不像Windows一样,接上新硬件后可以自动识别,在Linux下无法自动识别新硬件的,需要手动去识别.USB移动存储设备通常被识别为sda1,具体可以通过fdisk -l命令查询. 在使用U盘前,我们先要为外挂点新建一个子目录,一般外挂点的子目录都是建立在/mnt里面的,我们也建在那里,当然也可以建在/目录下,名字可以自己定,我们就取名为usb,终端下的命令如下: mkdir /mnt/usb 然后我们就可以接上我的U盘了,然后在终端下输入命令并击Enter键即可: mo

Linux下常用的shell命令记录

本文章记录我在linux系统下常用或有用的系统级命令,包括软硬件查看.修改命令,有CPU.内存.硬盘.网络.系统管理等命令.但本文不打算介绍生僻命令,也不介绍各个linux发行版下的特有命令,且以后会持续更新. 说明,我是在一个Centos 6.4 64位的虚拟机系统进行测试.本文介绍的命令都会在此Centos下运行验证(也有部分命令会在我的suse/ubuntu系统里测试的,会做特明说明),但运行结果就不再列出了. 硬件篇 CPU相关 lscpu                   #查看的是

linux下FTP下创建虚拟账户db_load

Linux_FTP配置虚拟用户问题 执行db_load -T -t hash -f login.txt /etc/vsftpd/vsftpd_login.db时报错 -bash: db_load -T -t hash -f login.txt /etc/vsftpd/vsftpd_login.db: No such file or directory db_load应该linux下创建虚拟账户: 选项-T允许应用程序能够文本文件转译载入进数据库由于我们之虚拟用户信息文件方式存储文件里了让Vsft

Linux用户空间与内核空间(理解高端内存)

Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中.   Linux内核地址映射模型 x86 CPU采用了段页式地址映射模型.进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存. 段页式机制如下图.   Linux内核地址空间划分 通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间.注意这里

linux下CentOS6.0安装配置图文教程

1.1 系统简介 CentOS 是什么? CentOS是一个基于Red Hat 企业级 Linux 提供的可自由使用的源代码企业级的 Linux 发行版本.每个版本的 CentOS 都会获得七年的支持(通过安全更新方式).新版本的 CentOS 每两年发行一次,而每个版本的 CentOS 会定期(大概每六个月)更新一次,以便支持新的硬件.这样,建立一个安全.低维护.稳定.高预测性.高重复性的 Linux 环境. CentOS(Community Enterprise Operating Syst

linux下bus、devices和platform的基础模型 【转】

转自:http://blog.chinaunix.net/uid-20672257-id-3147337.html 一.kobject的定义:kobject是Linux2.6引入的设备管理机制,在内核中由struct kobject结构表示,这个结构使所有设备在底层都具有统一的接口.kobject提供了基本的对象管理能力,是构成Linux2.6设备模型的核心结构,它与sysfs文件系统紧密联系,每个在内核中注册kobject对象都对应与sysfs文件系统中的一个目录;kobject--->sys

Linux下LCD 10分钟自动关屏的问题总结

Linux下的LCD驱动默认10分钟后会自动关闭屏幕,我们可以修改一下代码让其不自动关屏 在有一个 drivers/char/vt.c 文件其中有一个变量(blankinterval)可以设置它来修改自动关屏的时间,也可以在函数(blank_screen_t)开头直接返回,这样就永远不会关屏了   在用LCD显示的时候,发现10分钟LCD就不再工作了.确实,Linux下有一个参数blankinterval的值就是10*60*Hz. 它决定了LCD只显示10分钟,然后LCD控制器就被关掉了. 具体