uevent
uevent是kobject的一部分,用于在kobject状态发生改变时,例如增加、移除等,通知用户空间程序。用户空间程序收到这样的事件后,会做相应的处理。
该机制通常是用来支持热拔插设备的,例如U盘插入后,USB相关的驱动软件会动态创建用于表示该U盘的device结构(相应的也包括其中的kobject),并告知用户空间程序,为该U盘动态的创建/dev/目录下的设备节点,更进一步,可以通知其它的应用程序,将该U盘设备mount到系统中,从而动态的支持该设备。
uevent的机制是比较简单的,设备模型中任何设备有事件需要上报时,会触发uevent提供的接口。uevent模块准备好上报事件的格式后,可以通过两个途径把事件上报到用户空间:一种是通过kmod模块,直接调用用户空间的可执行文件;另一种是通过netlink通信机制,将事件从内核空间传递给用户空间。
其中,netlink是一种socket,专门用来进行内核空间和用户空间的通信;kmod是管理内核模块的工具集,类似busybox,我们熟悉的lsmod,insmod等是指向kmod的链接。
uevent有几个核心的数据结构,按照惯例,先独立分析各个核心类,然后通过类之间的关系全面了解uevent机制。
kobject_action
kobject_action定义了event的类型,包括:
ADD/REMOVE,kobject(或上层数据结构)的添加/移除事件。
ONLINE/OFFLINE,kobject(或上层数据结构)的上线/下线事件,其实是是否使能。
CHANGE,kobject(或上层数据结构)的状态或者内容发生改变。
MOVE,kobject(或上层数据结构)更改名称或者更改parent(意味着在sysfs中更改了目录结构)。
CHANGE,如果设备驱动需要上报的事件不再上面事件的范围内,或者是自定义的事件,可以使用该event,并携带相应的参数。
kobj_uevent_env
前面有提到过,在利用Kmod向用户空间上报event事件时,会直接执行用户空间的可执行文件。而在Linux系统,可执行文件的执行,依赖于环境变量,因此kobj_uevent_env用于组织此次事件上报时的环境变量。
envp,指针数组,用于保存每个环境变量的地址,最多可支持的环境变量数量为UEVENT_NUM_ENVP。
envp_idx