一下所有分析均基于最新安卓系统android-4.4源码:
system/core/init/init.c:
INFO("reading config file\n");
init_parse_config_file("/init.rc");
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(keychord_init_action, "keychord_init");
queue_builtin_action(console_init_action, "console_init");
/* execute all the boot actions to get us started */
action_for_each_trigger("init", action_add_queue_tail);
/* skip mounting filesystems in charger mode */
if (!is_charger) {
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 (is_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_property_triggers");
#if BOOTCHART
queue_builtin_action(bootchart_init_action, "bootchart_init");
#endif
这是init程序main函数中的一段代码,涉及到trigger的主要是 action_for_each_trigger函数,该函数在此不做分析,可以参考其他文章,其主要作用是往action队列中添加action结构体。需要明白的一点:init在启动过程中会执行action队列中的所有action,执行按从头到尾顺利依次进行。因此,位于队列前面的先被执行。所以,先调用 action_for_each_trigger 函数的action将先被执行。
按照上面代码执行的顺序,可以列出trigger触发顺序依次是:
- early-init
- init
- early-fs *
- fs *
- post-fs *
- post-fs-data *
- early-boot *
- boot *
- charger **
带一个星号的为非charger模式执行,带两个星号的为charger模式执行。
清楚了这个执行顺序,安卓的整个启动顺序就很容易理清楚了。
安卓4.3.1默认init.rc文件包含early-init 、init 、post-fs、post-fs-data、boot 触发器
内容如下:
# Copyright (C) 2012 The Android Open Source Project
#
# IMPORTANT: Do not create world writable files or directories.
# This is a common source of Android security bugs.
#
import /init.usb.rc
import /init.${ro.hardware}.rc
import /init.trace.rc
on early-init
# Set init and its forked children's oom_adj.
write /proc/1/oom_adj -16
# Set the security context for the init process.
# This should occur before anything else (e.g. ueventd) is started.
setcon u:r:init:s0
# Set the security context of /adb_keys if present.
restorecon /adb_keys
start ueventd
# create mountpoints
mkdir /mnt 0775 root system
on init
sysclktz 0
loglevel 3
# setup the global environment
export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
export LD_LIBRARY_PATH /vendor/lib:/system/lib
export ANDROID_BOOTLOGO 1
export ANDROID_ROOT /system
export ANDROID_ASSETS /system/app
export ANDROID_DATA /data
export ANDROID_STORAGE /storage
export ASEC_MOUNTPOINT /mnt/asec
export LOOP_MOUNTPOINT /mnt/obb
export BOOTCLASSPATH /system/framework/core.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/s