一、Linux Udev和Uevent机制介绍
linux内核最初的设备管理是通过devfs来实现的,但是由于诸多问题,如不确定的设备映射、设备号不足、设备文件过多以及命名不灵活等,出现了新的设备管理策略udev。
udev则是devfs的替代者,是一个在用户空间运行的程序,用于动态管理设备节点。它利用Linux内核提供的uevent机制,在系统启动时运行一个守护进程udevd,通过监听内核发送的uevent来执行相应的热插拔动作。这些动作包括创建或删除设备节点、加载或卸载驱动模块等。与devfs相比,udev提供了更加灵活和强大的设备管理能力,能够自动处理设备的添加、删除和修改,使得设备文件的管理更加便捷和高效。
Linux的uevent是一种事件通知机制,uevent是kobject的一部分,用于在kobject状态发生改变时(增加、移除等),通知用户空间程序。uevent代表“用户事件”,它允许设备驱动程序和其他内核子系统在设备插入、移除、配置或其他相关事件发生时发送消息给用户空间。
当一个设备插入到系统中时,内核会生成一个uevent并发送给用户空间的udev守护进程。udev进程负责接收uevent消息,并根据消息的内容进行设备管理和配置。udev可以根据设备的属性信息,为设备创建设备节点文件、加载驱动程序、设置设备权限等。
uevent消息是通过netlink套接字发送和接收的。内核通过sysfs文件系统中的设备属性来获取设备的状态信息,并将这些属性作为uevent消息的一部分发送给用户空间。用户空间可以通过监视netlink套接字上的事件来接收uevent消息,并根据消息的内容进行相应的操作。
uevent机制的存在使得用户空间不再需要花费大量的时间和性能遍历sysfs,去寻找各种细微的变化。这对于Linux下设备的自动发现和挂载有重要作用。同时,uevent也并非仅限于sysfs中节点的创建和删除,内核空间也可以向用户空间发送含有指定信息的自定义uevent,触发用户空间的指定事件。
二、Android ueventd
1、uevent上报事件流程图
2、/dev设备创建流程及上报
device_register->
device_add->
kobject_uevent(&dev->kobj, KOBJ_ADD)->
kobject_uevent_env->
add_uevent_var //添加参数
...
add_uevent_var
kobject_uevent_net_broadcast->
uevent_net_broadcast_untagged //发送uevent事件
3、ueventd coldboot
ueventd是如何处理进程启动之前的uevent事件的,下面的连接解释的很清楚:
https://android.googlesource.com/platform/system/core/+/master/init/README.ueventd.md
翻译:
为了在ueventd启动之前为所有已经发送了其uevent事件的设备在/dev中创建设备节点,当ueventd启动时,它会对/sys执行所谓的“冷引导(coldboot)”。在此过程中,它会对其在/sys/class、/sys/block和/sys/devices中找到的所有“uevent”文件写入“add”,这会导致内核重新生成这些路径的uevent事件,从而使ueventd创建节点。