2. return ueventd_main(argc, argv);
6) 生成 Android 系统中的一些基本的系统目录并挂载对应的文件系统。
/* clear the umask */
umask(0);
/* Get the basic filesystem setup we need put
* together in the initramdisk on / and then we'll
* let the rc file figure out the rest.
*/
mkdir("/dev", 0755);
mkdir("/proc", 0755);
mkdir("/sys", 0755);
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
mount("proc", "/proc", "proc", 0, NULL);
mount("sysfs", "/sys", "sysfs", 0, NULL);
/* indicate that booting is in progress to background fw loaders, etc
*/
close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));
/* We must have some place other than / to create the
* device nodes for kmsg and null, otherwise we won't
* be able to remount / read-only later on.
* Now that tmpfs is mounted on /dev, we can actually
* talk to the outside world.
*/
7) 生成 “/dev/__null__” 虚拟设备(类似于 Linux 系统中的 /dev/null 设备)并将
stdin/stdout/stderr 三个文件重定向到 “/dev/__null__”
open_devnull_stdio();
8) 生成 ” /dev/__kmsg__” 虚拟设备用于记录 log。
Klog_init 实现文件: system/core//libcutils/klog.c
klog_init();
INFO("reading config filen");
9) 解析 init.rc (platform/system/core/rootdir/init.rc)。
3. init_parse_config_file("/init.rc");
/* pull the kernel commandline and ramdisk properties file in */
10) 从 “/proc/cmdline” 中读取内核命令行参数,
对应函数实现路径: platform/system/core/init/util.c
import_kernel_cmdline(0, import_kernel_nv);
11) 在第 10 步读取完 /proc/cmdline 中的参数后,修改此文件的权限,禁止非授权
用户操作此文件。
/* don't expose the raw commandline to nonpriv processes */
chmod("/proc/cmdline", 0440);
12) 从 “/proc/cpuinfo” 中读取系统的 CPU 硬件信息。
对应函数实现路径: platform/system/core/init/util.c
get_hardware_name(hardware, &revision);
13) 基于第 12 步中读取的硬件信息来解析特定于硬件的配置信息。
snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
init_parse_config_file(tmp);
14) 基 于 ”early-init”,”property_init”,”keychord_init”,”console_init” 标 识 , 使 用 ”
queue_builtin_action”来过滤上述操作中解析的 init.rc 文件中的 action, 并将符合
条 件 的 action 添 加 到 对 应 的 action_queue 中 , 然 后 调 用 ”
action_for_each_trigger”来运行这些 actions(实际上是 action 在 list 中的分类移
动操作)。
对应函数实现路径: platform/system/core/init/init_parser.c
基于下面的运行逻辑可以看出,运行”init.rc”中的 action 的顺序为:
“early-init” -> “init” -> “early-boot” -> “boot”
action_for_each_trigger("early-init", action_add_queue_tail);
queue_builtin_action(wait_for_coldboot_done_action,
"wait_for_coldboot_done");
queue_builtin_action(property_init_action, "property_init");
queue_builtin_action(keychord_init_action, "keychord_init");
queue_builtin_action(console_init_action, "console_init");
queue_builtin_action(set_init_properties_action,
"set_init_properties");
/* execute all the boot actions to get us started */
action_for_each_trigger("init", action_add_queue_tail);
4. /* skip mounting filesystems in charger mode */
if (strcmp(bootmode, "charger") != 0)
{
action_for_each_trigger("early-fs", action_add_queue_tail);
action_for_each_trigger("fs", action_add_queue_tail);
action_for_each_trigger("post-fs", action_add_queue_tail);
action_for_each_trigger("post-fs-data", action_add_queue_tail);
}
queue_builtin_action(property_service_init_action,
"property_service_init");
queue_builtin_action(signal_init_action, "signal_init");
queue_builtin_action(check_startup_action, "check_startup");
if (!strcmp(bootmode, "charger"))
{
action_for_each_trigger("charger", action_add_queue_tail);
}
else
{
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
}
/* run all property triggers based on current state of the properties
*/
queue_builtin_action(queue_property_triggers_action,
"queue_propety_triggers");
#if BOOTCHART
queue_builtin_action(bootchart_init_action, "bootchart_init");
#endif
15) “init” 进程开始进行”循环事件处理”逻辑。
for (;;)
{
int nr, i, timeout = -1;
16) 运行第 14 步操作中所分类整理的 action_queue 中对应的 action。
execute_one_command();
17) 查看当前的服务进程状态,如果有服务进程退出,重启对应服务进程。
restart_processes();