一、启动
ueventd在init.rc(@/system/core/rootdir)中启动.
on early-init
... ...
start ueventd
/sbin/ueventd是/init的link,故最终执行的是/init。其代码如下:@/system/init/init.c
if (!strcmp(basename(argv[0]), "ueventd"))
return ueventd_main(argc, argv);
二、代码分析
int ueventd_main(int argc, char **argv)
{
struct pollfd ufd;
int nr;
char tmp[32];
/* Prevent fire-and-forget children from becoming zombies.
* If we should need to wait() for some children in the future
* (as opposed to none right now), double-forking here instead
* of ignoring SIGCHLD may be the better solution.
*/
signal(SIGCHLD, SIG_IGN);
open_devnull_stdio(); //创建并打开"/dev/__kmsg__",将stdin/stdout/stderr三个文件重定向到 "/dev/__null__"
klog_init(); //创建并打开"/dev/__kmsg__" 虚拟设备用于记录log
INFO("starting ueventd\n");
/* Respect hardware passed in through the kernel cmd line. Here we will look
* for androidboot.hardware param in kernel cmdline, and save its value in
* hardware[]. */
import_kernel_cmdline(0, import_kernel_nv); //解析kernel commandline,从中查找hardware
get_hardware_name(hardware, &revision); //从/proc/cupinfo中获取hardware
ueventd_parse_config_file("/ueventd.rc"); //解析.rc设置
snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);
ueventd_parse_config_file(tmp);
device_init(); //如果coldboot尚未完成,完成之(触发/sys/classes /sys/block /sys/devices中设备add uevent,并处理
ufd.events = POLLIN;
ufd.fd = get_device_fd();
while(1) {
ufd.revents = 0;
nr = poll(&ufd, 1, -1); //poll uevent
if (nr <= 0)
continue;
if (ufd.revents == POLLIN)
handle_device_fd();
}
}
收到uevent, 创建/删除相应的设备文件(/dev/xxx)和link (/sys/xxx).