目录
一、Android Boot Process OverView
二、Android Boot Process Source Code Analysis
2.1 init 进程(system/core/init/init.cpp::main())
2.2 Native Daemons
2.3 Zygote & Android Runtime
2.4 System Server
2.5 Activity Manager
2.6 Launcher
2.7 Boot Completed
三、Android Boot Process Vital Log Analysis
虽然本博文不涉及kernel等相关的内容,但是我们还是要从一个宏观的角度来了解android整机开机的启动流程,如下图1.
图1 Android Boot Process Full
图2 Android Boot Process Detail
1.1 CPU(Bootrom):bootrom是嵌入到处理器芯片中的一块写保护的区域,它包含了最初始的一部分代码,当我们重启或者按下电源键时,处理器会首先将该区域的代码加载到内存中并执行。
1.2 Bootloader:Bootloader由bootrom启动,而bootloader的作用就是一个引导程序,按照实现定义好的步骤一步步执行,包括将一些配置参数或系统文件加载到内存当中。参考网络上的解释可分为两部分(后面会去钻研证实)
1. init.S 初始化堆栈,清零BSS段,调用main.c的_main() 函数。
2. main.c 初始化硬件(闹钟、主板、键盘、控制台),创建 linux 标签。
1.3 Kernel:设置缓存,被保护内存,调度和加载驱动。当驱动完成系统设置后的第一件事就是在系统文件中寻找并启动init进程,也就是系统的根进程,或者说第一个进程。在这里,kernel_init通过调用run_init_process("/init”)(android/kernel/msm-4.9/init/mian.c::kernel_init()),开始执行init程序,并从kernel进程转化为第一个用户进程。
1.4 Init:Android根进程,init在启动过程中会创建/dev,/proc、/sys等目录,挂载tmpfs临时分区、创建如/dev/kmsg、/dev/random等设备节点,并提供属性服务,解析init.rc,并本地化一些守护进程,如Service Manager、Meida Server等。通过解析Init.rc,触发启动其中定义好的Action和Service如:
on early-init:设置init进程以及它创建的子进程的优先级,设置init进程的安全环境
on init:设置全局环境,为cpu accounting创建cgroup(资源控制)挂载点
on fs:挂载mtd分区
on post-fs:改变系统目录的访问权限
on post-fs-data:改变/data目录以及它的子目录的访问权限
on boot:基本网络的初始化,内存管理等等
service servicemanager:启动系统管理器管理所有的本地服务,比如位置、音频、Shared preference等等…
service zygote:启动zygote作为应用进程
1.5 Zygote:Zygote是一个特殊的Android 系统进程,在启动Zygote的过程中会创建ART VM(Art的原理基于AOT,即ahead of time),然后通过Art VM共享代码。Zygote启动时会将一些核心库类进行预加载以及初始化(通常,这些核心类一般是只读的,这也是 Android SDK 或者核心框架的一部分)。 那么当我们去启动app的时候,将会占用更小的内存,而且启动速度也大大得到了提高(即app启动所需要的资源或者类库已经在开机初期被预加载到内存了,app启动或运行需要的资源和类库可以直接去内存中取)。 当我们需要启动一个app的时候,zygote会通过socket监听到这个请求,然后fork一个自己的副本作为子进程(这个副本并不是立即copy zygote的资源,而是在新进程执行的时候才会去拷贝。这个foke特性源自Linux kernel的copy-on-write写时拷贝技术。Foke会涉及到创建新的进程)。当一个新进程被创建启动的时候,它除了拷贝zygote的资源,也会从内存中拷贝系统类和资源,且仅拷贝一份。Zygote的设计除了用于Foke一个新的app,还有一个关键的作用就是启动System Server进程。
1.6 System Server:System Server是Zygote第一个启动的进程,System Server启动之后会作为一个独立的进程来运行。它的作用主要用于初始化每一个系统服务,并在之前启动的System Manager中注册这些服务。当然,它也会启动Activity Manager;
1.7 Activity Manager:Activity Manager的作用主要是创建新的Activity线程,维护着Activity的生命周期,并管理者Activity栈。在Activity Manager启动的最后阶段会通过Intent,启动一个Home Launcher;也就是我们看到最多的桌面程序。
2.1.1 main()函数
2.1.1.1 创建设备节点
ueventd_main(argc, argv) --> LOG(INFO) << "ueventd started!"; --> LOG(INFO) << "ueventd started!";
init进程启动时会通过该函数创建子进程ueventd,并通过ueventd创建设备节点,处理ok打印“ueventd started!”日志,接着继续监听来自驱动的uevent,进行“热插拔”处理。
2.1.1.2 kerne态看门狗
watchdogd_main(argc, argv)
“看门狗”本身是一个定时器电路,内部会不断的进行计时(或计数)操作,计算机系统和”看门狗”有两个引脚相连接,正常运行时每隔一段时间就会通过其中一个引脚向”看门狗”发送信号,”看门狗”接收到信号后会将计时器清零并重新开始计时,而一旦系统出现问题,进入死循环或任何阻塞状态,不能及时发送信号让”看门狗”的计时器清零,当计时结束时,”看门狗”就会通过另一个引脚向系统发送“复位信号”,让系统整机重启。watchdogd_main主要是定时器作用,而DEV_NAME就是那个引脚。
2.1.1.3 kernel log重定向
InitKernelLogging(argv)
platform/system/core/base/logging.cpp
初始化日志输出;首先是将标准输入输出重定向到”/sys/fs/selinux/null”,然后调用InitLogging初始化log日志系统,然后通过getenv("ANDROID_LOG_TAGS");函数获取系统当前日志输出等级,根据日志等级进行log的输出。
在InitKernelLogging方法中有句调用android::base::InitLogging(argv, &android::base::KernelLogger);这句的作用就是将KernelLogger函数作为log日志的处理函数,KernelLogger主要作用就是将要输出的日志格式化之后写入到 /dev/kmsg 设备中
LOG(INFO) << "ueventd started!";//这是init打印的第一条日志;抓取开机log,这条日志详细信息如下:
08-10 14:15:56.381 <14>[ 2.878528] [1, init]init: init first stage started!
从这条log上可以看到,init进程号为1,在启动frist state的时候,时间大约在2.8s左右。
2.1.1.4 载入SELinux策略
selinux_initialize(true);//设置载入SELinux安全策略,
if (selinux_android_restorecon("/init", 0) == -1) {//restorecon命令用来恢复SELinux文件属性即恢复文件的安全上下文
2.1.1.5 进入第二阶段
setenv("INIT_SECOND_STAGE", "true", 1);
execv(path, args);//重新执行main方法,进入第二阶段,然后再次进入init的main函数,启动用户态的init进程。
InitKernelLogging(argv); //初始化日志输出
LOG(INFO) << "init second stage started!";//打印进入第二阶段的关键日志
tips:
进入第二阶段的函数execv原型如下:
函数原型
int execv(const char *progname, char *const argv[]); //#include
功能介绍
execv会停止执行当前的进程,并且以progname应用进程替换被停止执行的进程,进程ID没有改变。
参数:
progname: 被执行的应用程序。
argv: 传递给应用程序的参数列表, 注意,这个数组的第一个参数应该是应用程序名字本身,并且最后一个参数应该为NULL,不参将多个参数合并为一个参数放入数组。
返回值:
如果应用程序正常执行完毕,那么execv是永远不会返回的;当execv在调用出错了,此时它的返回值应该是-1,具体的错误代码可以通过全局变量errno查看,还可以通过stderr得到具体的错误描述字符。
2.1.1.6 初始化属性系统,从指定文件中读取属性
property_init();
初始化属性系统区域的,应该是分门别类更准确些,首先清除缓存,这里主要是清除几个链表以及在内存中的映射,新建property_filename目录,这个目录的值为 /dev/_properties;然后就是调用initialize_properties加载一些系统属性的类别信息,最后将加载的链表写入文件并映射到内存
2.1.1.7
process_kernel_dt();
读取DT(设备树)的属性信息,然后通过 property_set 设置系统属性
2.1.1.8 导入cmdline
"/proc/cmdline"
process_kernel_cmdline(); --> import_kernel_cmdline(); --> import_kernel_nv();
export_kernel_boot_props();
这里通过process_kernel_cmdline()函数调用import_kernel_cmdline()函数将"/proc/cmdline"中信息分割成一个个的键值对,并最终已key、value的方式设置为ro属性(property_set("ro.kernel." + key, value););如以"androidboot."开始的key将会以ro.boot.+subkey+value的形式设置为ro属性(property_set("ro.boot." + key.substr(12), value);)。
举例如下:
以下cmdline①会被解析为②:
①:
rcupdate.rcu_expedited=1 console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0 earlycon=msm_serial_dm,0xc170000 androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x37 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 sched_enable_hmp=1 sched_enable_power_aware=1 service_locator.enable=1 swiotlb=1 androidboot.configfs=true androidboot.usbcontroller=a800000.dwc3 buildvariant=userdebug root=/dev/dm-0 dm="system none ro,0 1 android-verity /dev/mmcblk0p65" androidboot.verifiedbootstate=orange androidboot.keymaster=1 androidboot.veritymode=logging androidboot.bootdevice=c0c4000.sdhci androidboot.serialno=5d9aa8f0 androidboot.baseband=sdm mdss_mdp.panel=1:dsi:0:qcom,mdss_dsi_td4310_djn_fhdp_video:config0:1:none:cfg:single_dsi board_id=S88661BA1 hw_id=REV0.4 androidboot.usbst1=0x00
②:
[ro.boot.baseband]: [sdm]
[ro.boot.bootdevice]: [c0c4000.sdhci]
[ro.boot.configfs]: [true]
[ro.boot.console]: [ttyMSM0]
[ro.boot.hardware]: [qcom]
[ro.boot.keymaster]: [1]
[ro.boot.serialno]: [5d9aa8f0]
[ro.boot.usbcontroller]: [a800000.dwc3]
[ro.boot.usbst1]: [0x00]
[ro.boot.verifiedbootstate]: [orange]
[ro.boot.veritymode]: [logging]
export_kernel_boot_props();这里将一些ro属性做了一些映射如下:
{ "ro.boot.serialno", "ro.serialno", "", },
{ "ro.boot.mode", "ro.bootmode", "unknown", },
{ "ro.boot.baseband", "ro.baseband", "unknown", },
{ "ro.boot.bootloader", "ro.bootloader", "unknown", },
{ "ro.boot.hardware", "ro.hardware", "unknown", },
{ "ro.boot.revision", "ro.revision", "0", },
2.1.1.9为第二阶段初始化selinux策略,通过参数来执行不同的逻辑
selinux_initialize(false);
selinux_restore_context();
2.1.1.10
epoll_create1
EPOLL类似于POLL,是Linux中用来做事件触发的,对于大量的描述符处理,EPOLL更有优势。epoll_create1是epoll_create的升级版,函数是在linux 2.6.27中加入的,它可以动态调整epoll实例中文件描述符的个数,EPOLL_CLOEXEC这个参数是为文件描述符添加O_CLOEXEC属性
2.1.1.11 加载其他系统属性,并系统属性服务
property_load_boot_defaults();通过以下操作加载其他系统属性:
load_properties_from_file("/system/etc/prop.default", NULL))
load_properties_from_file("/prop.default", NULL))
load_properties_from_file("/default.prop", NULL)
load_properties_from_file("/odm/default.prop", NULL)
load_properties_from_file("/vendor/default.prop", NULL);
start_property_service();
2.1.1.12 解析init.rc
ParseConfig()根据传入的参数不同而执行不同的逻辑,如如果是parser.ParseConfig("/init.rc")就调用ParseConfigFile函数解析init.rc文件;如果是parser.ParseConfig("/system/etc/init"));或parser.ParseConfig("/vendor/etc/init"));就去遍历对应的目录解析目录下的*.rc文件;最终会调用ParseData()函数将*.rc文件中的action、service、import等内容解析出来,并合并相同的action。详细如下:
通过Action解析器ActionParser将*.rc中的action解析为如下格式的一个map:
命令 最小参数 最大参数 函数
{"bootchart", {1, 1, do_bootchart}},
{"chmod", {2, 2, do_chmod}},
{"chown", {2, 3, do_chown}},
{"class_reset", {1, 1, do_class_reset}},
{"class_restart", {1, 1, do_class_restart}},
{"class_start", {1, 1, do_class_start}},
{"class_stop", {1, 1, do_class_stop}},
{"copy", {2, 2, do_copy}},
{"domainname", {1, 1, do_domainname}},
{"enable", {1, 1, do_enable}},
{"exec", {1, kMax, do_exec}},
{"exec_start", {1, 1, do_exec_start}},
{"export", {2, 2, do_export}},
{"hostname", {1, 1, do_hostname}},
{"ifup", {1, 1, do_ifup}},
{"init_user0", {0, 0, do_init_user0}},
{"insmod", {1, kMax, do_insmod}},
{"installkey", {1, 1, do_installkey}},
{"load_persist_props", {0, 0, do_load_persist_props}},
{"load_system_props", {0, 0, do_load_system_props}},
{"loglevel", {1, 1, do_loglevel}},
{"mkdir", {1, 4, do_mkdir}},
{"mount_all", {1, kMax, do_mount_all}},
{"mount", {3, kMax, do_mount}},
{"umount", {1, 1, do_umount}},
{"restart", {1, 1, do_restart}},
{"restorecon", {1, kMax, do_restorecon}},
{"restorecon_recursive", {1, kMax, do_restorecon_recursive}},
{"rm", {1, 1, do_rm}},
{"rmdir", {1, 1, do_rmdir}},
{"setprop", {2, 2, do_setprop}},
{"setrlimit", {3, 3, do_setrlimit}},
{"start", {1, 1, do_start}},
{"stop", {1, 1, do_stop}},
{"swapon_all", {1, 1, do_swapon_all}},
{"symlink", {2, 2, do_symlink}},
{"sysclktz", {1, 1, do_sysclktz}},
{"trigger", {1, 1, do_trigger}},
{"verity_load_state", {0, 0, do_verity_load_state}},
{"verity_update_state", {0, 0, do_verity_update_state}},
{"wait", {1, 2, do_wait}},
{"wait_for_prop", {2, 2, do_wait_for_prop}},
{"write", {2, 2, do_write}},
通过服务解析器ServiceParser将服务解析出并创建一个对应的Service对象,对象相关的属性则被以下面的方式记录起来。
{"capabilities",{1, kMax, &Service::ParseCapabilities}},
{"class", {1, kMax, &Service::ParseClass}},
{"console", {0, 1, &Service::ParseConsole}},
{"critical", {0, 0, &Service::ParseCritical}},
{"disabled", {0, 0, &Service::ParseDisabled}},
{"group", {1, NR_SVC_SUPP_GIDS + 1, &Service::ParseGroup}},
{"ioprio", {2, 2, &Service::ParseIoprio}},
{"priority", {1, 1, &Service::ParsePriority}},
{"keycodes", {1, kMax, &Service::ParseKeycodes}},
{"oneshot", {0, 0, &Service::ParseOneshot}},
{"onrestart", {1, kMax, &Service::ParseOnrestart}},
{"oom_score_adjust",{1, 1, &Service::ParseOomScoreAdjust}},
{"memcg.swappiness",{1, 1, &Service::ParseMemcgSwappiness}},
{"memcg.soft_limit_in_bytes",{1, 1, &Service::ParseMemcgSoftLimitInBytes}},
{"memcg.limit_in_bytes", {1, 1, &Service::ParseMemcgLimitInBytes}},
{"namespace", {1, 2, &Service::ParseNamespace}},
{"seclabel", {1, 1, &Service::ParseSeclabel}},
{"setenv", {2, 2, &Service::ParseSetenv}},
{"shutdown", {1, 1, &Service::ParseShutdown}},
{"socket", {3, 6, &Service::ParseSocket}},
{"file", {2, 2, &Service::ParseFile}},
{"user", {1, 1, &Service::ParseUser}},
{"writepid", {1, kMax, &Service::ParseWritepid}},
ImportParser则主要导入一些其他的rc文件进来。
2.1.1.13 设置触发器,触发init.rc中关键action,顺序如下:
am.QueueEventTrigger("early-init");//这里触发init.rc中的early-init事件,下同
am.QueueEventTrigger("init");
am.QueueEventTrigger("late-init");
trigger early-fs
trigger fs
trigger post-fs
trigger late-fs
trigger post-fs-data
trigger zygote-start
trigger load_persist_props_action
trigger firmware_mounts_complete
trigger early-boot
trigger boot
class_start hal
class_start core
on property:sys.boot_completed=1
bootchart stop
2.1.1.14
restart_processes()
restart_processes调用的其实是ForEachServiceWithFlags函数,这个函数主要是遍历services_数组,比较它们的flags是否是SVC_RESTARTING,也就是当前service是否是等待重启的,如果是就执行它的RestartIfNeeded函数。RestartIfNeeded()函数将主要工作交给了Start,也就是具体的启动service,但是交给它之前做了一些判断,也就是5秒内只能启动一个服务,如果有多个服务,那么后续的服务将进入等待
init在解析init.rc过程中会启动一些守护进程如下:
//Daemon processes to be run by init.
service ueventd /sbin/ueventd
service servicemanager /system/bin/servicemanager
service healthd /system/bin/healthd
service console /system/bin/sh
service logd /system/bin/logd
......
2.3.1 启动zygote二进制程序
在init.rc文件中的导入其他rc文件部分,有这样一句话:
import /init.${ro.zygote}.rc
即会根据系统ro属性ro.zygote来导入对应的属性值的rc文件,如
getprop "ro.zygote"
zygote64_32
那么我们需要导入的文件即为zygote64_32.rc文件,即会启动两个 zygote 进程 (名为 zygote 和 zygote_secondary),对应的执行程序分别是 app_process64 (主模式)、app_process32
/system/core/rootdir/init.zygote64_32.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
如前面通过trigger zygote-start的启动zygote的顺序如下:
trigger zygote-start
trigger zygote//触发启动zygote服务
trigger zygote-secondary
如上,trigger zygote通过start映射的do_start函数并接受/system/bin/app_process64作为service对应的可执行程序;当执行app_process64二进制程序时,接下来进入zygote的main函数:
2.3.2 app_main::main()
/frameworks/base/cmds/app_process/app_main.cpp
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));//构建AppRuntime对象,并将参数传入
if (!className.isEmpty()) {//如果className不为空,说明是application启动模式
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//确认启动zygote,而非appliction
if (startReg(env) < 0) {//注册JNI函数
2.3.3 AndroidRuntime::start()
/frameworks/base/core/jni/AndroidRuntime.cpp
jni_invocation.Init(NULL);//初始化JNI,加载libart.so
if (startVm(&mJavaVM, &env, zygote) != 0) {//创建虚拟机
2.3.4 JniInvocation::Init()
定义在platform/libnativehelper/JniInvocation.cpp
Init函数主要作用是初始化JNI,具体工作是首先通过dlopen加载libart.so获得其句柄,然后调用dlsym从libart.so中找到
JNI_GetDefaultJavaVMInitArgs、JNI_CreateJavaVM、JNI_GetCreatedJavaVMs三个函数地址,赋值给对应成员属性,
这三个函数会在后续虚拟机创建中调用.
2.3.5 AndroidRuntime::startVm()
从各种系统属性中读取一些参数,然后通过addOption设置到AndroidRuntime的mOptions数组中存起来,另外就是调用之前从libart.so中找到JNI_CreateJavaVM函数,并将这些参数传入JNI_CreateJavaVM函数,然后在虚拟机创建完成后,动态注册一些native函数.
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{
......
/*
* Initialize the VM.
*
* The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
* If this call succeeds, the VM is ready, and we can start issuing
* JNI calls.
*/
if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
ALOGE("JNI_CreateJavaVM failed\n");
return -1;
}
return 0;
}
2.3.6 AndroidRuntime::startReg()
startReg首先是设置了Android创建线程的处理函数,然后创建了一个200容量的局部引用作用域,用于确保不会出现OutOfMemoryException,最后就是调用register_jni_procs进行JNI注册
2.3.7 AndroidRuntime::register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
register_jni_procs传入的RegJNIRec数组gRegJNI,里面就是一堆的函数指针
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
for (size_t i = 0; i < count; i++) {
if (array[i].mProc(env) < 0) {
#ifndef NDEBUG
ALOGD("----------!!! %s failed to load\n", array[i].mName);
#endif
return -1;
}
}
return 0;
}
如下函数数组:
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_util_MemoryIntArray),
REG_JNI(register_android_util_PathParser),
REG_JNI(register_android_app_admin_SecurityLog),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
REG_JNI(register_android_content_XmlBlock),
REG_JNI(register_android_text_AndroidCharacter),
REG_JNI(register_android_text_StaticLayout),
......
2.3.8 反射调用ZygoteInit类的main函数
虚拟机创建完成后,我们就可以用JNI反射调用Java了,直接是CallStaticVoidMethod反射调用ZygoteInit的main函数
env->CallStaticVoidMethod(startClass, startMeth, strArray);//调用main函数
2.3.9 ZygoteInit.main()
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
zygoteServer.registerServerSocket(socketName);//调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService等通讯;
preload(bootTimingsTraceLog);//预加载一些类与资源;
forkSystemServer(abiList, socketName, zygoteServer);//fork子进程,即System Server进程;forkSystemServer()并不是在函数体内直接调用Java类的main()函数的,而是通过抛异常的方式。详细可查看:Android系统启动-SystemServer上篇
return handleSystemServerProcess(parsedArgs);//进入子进程System Server
2.4.1 main()实例化SystemServer对象并执行run()
new SystemServer().run()
2.4.2 run()启动各种服务
2.4.2.1 createSystemContext();//初始化系统上下文,通过创建ActivityThread中的systemMain函数来创建ActivityThread对象,然后通过ActivityThread对象可以得到相关Context,如下:
getSystemContext()
getSystemUiContext()
相关函数如下:
/frameworks/base/services/java/com/android/server/SystemServer.java
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
/frameworks/base/core/java/android/app/ActivityThread.java
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}
2.4.2.2 创建SystemServiceManager对象
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
// Start services.
2.4.2.3 startBootstrapServices();
Installer.class//启动installd服务,通过installd服务创建如/data/user的关键目录,并为这些目录配置适当的权限。这部分需要在初始化其他服务之前完成。
DeviceIdentifiersPolicyService.class//在某些情况下我们需要去存取设备标识符,因此需要在activity manager初始化之前启动该服务;
ActivityManagerService.Lifecycle.class//启动最关键的服务之一AMS;
PowerManagerService.class//PMS服务由于被其他服务所以要优先启动。一些守护进程依赖它进行binder通信。
RecoverySystemService.class//启动该服务,以免某些情况下系统需要重启
LightsService.class//启动该服务已管理LCDs和显示背光
DisplayManagerService.class//需要在PMS启动前启动它。
PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);//启动PMS
UserManagerService.LifeCycle.class
new OverlayManagerService(mSystemContext, installer)
startSensorService();//启动sensor相关服务于,依赖PMS,app ops service, 和permissions service,在新线程中执行;
2.4.2.4 startCoreServices();//启动核心服务
DropBoxManagerService.class//记录错误和log的服务,如wtf()(What a Terrible Failure: Report a condition that should never happen. The error will always be logged at level ASSERT with the call stack. Depending on system configuration, a report may be added to the {@link android.os.DropBoxManager} and/or the process may be terminated immediately with an error dialog.)
BatteryService.class//电池电量,依赖LightService
UsageStatsService.class//应用程序使用情况统计服务
WebViewUpdateService.class
2.4.2.5 startOtherServices();//启动其他服务如我们熟知的AlarmManagerService.class、Watchdog、BluetoothService.class、InputMethodManagerService.Lifecycle.class、DeviceStorageMonitorService.class、FingerprintService.class
执行系统服务的systemRead函数,如wm.systemReady();等
启动systemui
startSystemUi(context, windowManagerF);
启动watchdog
Watchdog.getInstance().start();
调用系统服务的systemRunning()函数,如inputManagerF.systemRunning();等。
Tips:
在SystemServier启动各种服务的过程中,经常会调用SystemServiceManager中的startBootPhase函数来指示当前出于那个启动阶段如下:
startBootPhase()
Boot Phases被定义在SystemService.java中,如下:
/frameworks/base/services/core/java/com/android/server/SystemService.java:
PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; //在启动DisplayManagerService时调用;
PHASE_LOCK_SETTINGS_READY = 480;//在startOterServices()时设置,即在进入此阶段时,系统服务可通过持有锁,来完成数据初始化;
PHASE_SYSTEM_SERVICES_READY = 500;//在startOterServices()时设置,即在进入此阶段时,系统服务可以安全的调用系统核心服务,如PowerManager或者PackageManager;
PHASE_ACTIVITY_MANAGER_READY = 550;//在startOterServices()时设置,即在进入此阶段时,系统服务可以广播Intents;
PHASE_THIRD_PARTY_APPS_CAN_START = 600;//在startOterServices()时设置,即在进入此阶段时,系统服务可以启动或绑定第三方APP,也就是说此时APP可以与系统服务进行Binder通信;
PHASE_BOOT_COMPLETED = 1000;//在ActivityManagerService中的finishBooting()调用;那么当系统进入此阶段时,系统服务将允许用户与设备进行交互;也就是说此时系统已经完成启动;HomeApplication(如Launcher 桌面)已经完成启动。而且系统服务往往通过监听此阶段来知道系统是否启动完成,而非ACTION_BOOT_COMPLETED广播,因为ACTION_BOOT_COMPLETED广播有可能会发生延迟。
2.5.1 SystemServer中启动AMS相关操作如下:
startBootstrapServices阶段:
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();//开始启动AMS
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mActivityManagerService.initPowerManagement();//PowerManagerService启动后,通过AMS来初始化Power Manager的一些特性;
mActivityManagerService.setSystemProcess();//通过ServiceManager添加各种服务如AMS、ProcessStatsService、MemBinder、GraphicsBinder、DbBinder、CpuBInder、PermissionController、ProcessInfoService等,并通过获取ApplicationInfo对象,将android应用信息保存起来。
startCoreServices阶段:
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
startOtherServices阶段:
mActivityManagerService.installSystemProviders();//通过mSystemThread处理系统所有Providers,并创建CoreSettingsObserver实例,用于监控Settings的变化;创建FontScaleSettingObserver实例,监听字体的变化;
watchdog.init(context, mActivityManagerService);//watchdog监听AMS
mActivityManagerService.setWindowManager(wm);
mActivityManagerService.enterSafeMode();//如果当前检测到处于safemode,则进入safe mode;
mActivityManagerService.showSafeModeOverlay();
mActivityManagerService.systemReady()//此时Activity Manager可以运行三方代码,即此时可以启动应用程序了。
mActivityManagerService.startObservingNativeCrashes();//监视NativeCrashes
2.5.2 Lifecycle(Context context) 通过Lifecycle的构造函数构造出AMS的实例,并通过SystemServiceManager的startService的层层调用调用Lifecycle的onStart()函数,即最终调用AMS的start函数;
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
mService.start();
}
2.5.3 ActivityManagerService(Context systemContext)构造函数
创建前台线程,并获取启动该线程
mHandlerThread = new ServiceThread(TAG,
THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
获取前台线程的handler
mHandler = new MainHandler(mHandlerThread.getLooper());
创建UiHandler实例,并获取该UiHandler
mUiHandler = mInjector.getUiHandler(this);
创建后台线程,并获取启动该线程
sKillThread = new ServiceThread(TAG + ":kill",
THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
sKillThread.start();
下面两个超时时间的定义分别为前台广播和后台广播,它一个广播接受器在超时 前运行,如果超时,则放弃运行。
static final int BROADCAST_FG_TIMEOUT = 10*1000;
static final int BROADCAST_BG_TIMEOUT = 60*1000;
获取后台线程的handler
sKillHandler = new KillHandler(sKillThread.getLooper());
创建前台广播接受器实例。Android四大组件一:Broadcast
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", BROADCAST_FG_TIMEOUT, false);
创建后台广播接受器实例
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", BROADCAST_BG_TIMEOUT, true);
创建一个ActiveServices实例,并在构造函数中通过获取ro.config.max_starting_bg属性值来设置mMaxStartingBackground,如果属性值为0,则通过ActivityManager.isLowRamDeviceStatic()来判断当前是否为第ram,低ram为1,反之为8。
mServices = new ActiveServices(this);Android四大组件二:Service
创建一个ProviderMap实例,传入AMS实例给ProviderMap;Android四大组件三:Provider
mProviderMap = new ProviderMap(this);
创建一个AppErrors实例;
mAppErrors = new AppErrors(mUiContext, this);
创建data/system目录
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
创建一个BatteryStatsService实例;后面会将一些电池状态相关的文件保存到/data/system/目录下,如batterystats-checkin.bin、batterystats.bin、batterystats-daily.xml。
mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
创建ProcessStatsService实例,并创建/data/system/procstats文件,用于保存进程状态信息
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
Injector通过getAppOpsService函数创建AppOpsService实例,保存Appops相关权限管理信息到/data/system/appops.xml中
mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
通过AtomicFile创建urigrants.xml文件,AtomicFile的好处就是在操作文件之前会进行备份,在确认完全写入成功并同步到磁盘上之后再删除备份;如果发生异常的话,可以通过备份文件进行恢复,那么如果我们去读源文件的时候发现备份文件依然存在,那么就可以认为源文件脏污,这个时候会删除源文件,并从备份文件中进行恢复。
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
实例化UserController
mUserController = new UserController(this);
实例化VrController
mVrController = new VrController(this);
实例化ActivityStackSupervisor,即Activity的栈管理器,Activity的各种状态都是由它来管理的。Android四大组件四:Activity
mStackSupervisor = createStackSupervisor();
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
mTaskChangeNotificationController =
new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
实例化ActivityStarter,ActivityStarter在Activity启动的过程中负责搜集与Activity或者相关联的stack的intent和flags相关的信息。
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
实例化RecentTasks,RecentTasks是用来管理最近任务列表的一个类。
mRecentTasks = new RecentTasks(this, mStackSupervisor);
创建“CpuTracker”线程
mProcessCpuThread = new Thread("CpuTracker") {
建立framework层watchdog对AMS超时的监听
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
2.5.4 start()
mProcessCpuThread.start();//启动构造函数中CpuTracker线程
mBatteryStatsService.publish();//启动电池统计服务
mAppOpsService.publish(mContext);
2.5.8 systemReady()
goingCallback.run();//这段函数体在SystemServer类中有详细定义;
mUserController.onSystemReady();
mRecentTasks.onSystemReadyLocked();
mAppOpsService.systemReady();
mSystemServiceManager.startUser(currentUserId);//在该函数中通过回调函数,调用所有系统服务的onStartUser函数;
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);//启动persistent的app,具有persistent属性会在后台一直保持运行状态;
startHomeActivityLocked(currentUserId, "systemReady");//启动主程序
Intent(Intent.ACTION_USER_STARTED)和Intent(Intent.ACTION_USER_STARTING)//多用户相关
2.5.7 startHomeActivityLocked
Intent intent = getHomeIntent();//创建Intent,包含Action为Intent.ACTION_MAIN="android.intent.action.MAIN",Category为Intent.CATEGORY_HOME="android.intent.category.HOME";
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);//通过resolveActivityInfo函数向PMS查询所有Category为"android.intent.category.HOME"的Activity;并返回ResolveInfo,最终通过ResolveInfo获取对应的ActivityInfo;
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);//通过调用startActivityLocked最终调用我们所熟知的startActivity()来启动主应用程序;
这里贴下Launcher3的AndroidManifest.xml中的一段定义;
android:name="com.android.launcher3.Launcher" android:launchMode="singleTask" android:clearTaskOnLaunch="true" android:stateNotNeeded="true" android:windowSoftInputMode="adjustPan" android:screenOrientation="nosensor" android:configChanges="keyboard|keyboardHidden|navigation" android:resizeableActivity="true" android:resumeWhilePausing="true" android:taskAffinity="" android:enabled="true">
2.6.1如上所说,AMS通过调用startHomeActivityLocked开启了Launcher启动之路,从startActivityLocked()函数,到startActivity()函数,再到startActivity()函数,最终会调用startActivityUnchecked(),在startActivityUnchecked函数中会打印创建Launcher的Activity的日志,如下:
ActivityStack.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
01-01 06:50:24.432 1579 1618 I am_create_activity: [0,166559440,4,com.android.launcher3/.Launcher,android.intent.action.MAIN,NULL,NULL,268435712]
其他详细流程如下:
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java::resumeFocusedStackTopActivityLocked()//在Activity栈监听器中监听启动的Activity
resumeTopActivityUncheckedLocked()//在ActivityStack中启动对应的Activity
/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java::resumeTopActivityInnerLocked
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java::startSpecificActivityLocked()
startProcessLocked//由于launcher还没有启动,而且相关现成都为null,所以不会调用realStartActivityLocked()函数,而是直接startProcessLocked创建相关Activity线程;
startProcessLocked()函数中会打印以下log:
Slog.i(TAG, buf.toString());//main log
01-01 06:50:24.116 1579 1579 I ActivityManager: Start proc 3212:com.android.launcher3/u0a12 for service com.android.launcher3/.notification.NotificationListener
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(uid), startResult.pid, uid,
app.processName, hostingType,
hostingNameStr != null ? hostingNameStr : "");//event log
01-01 06:50:24.115 1579 1579 I am_proc_start: [0,3212,10012,com.android.launcher3,service,com.android.launcher3/.notification.NotificationListener]
最终调用Process.start()函数创建Launcher进程,并创建Activity;
01-01 06:50:24.432 1579 1618 I am_create_activity: [0,166559440,4,com.android.launcher3/.Launcher,android.intent.action.MAIN,NULL,NULL,268435712]
最后会通过checkFinishBootingLocked函数调用finishBooting()来最开机完成的收尾工作;
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java::finishBooting()
1.进入最后阶段-启动完成
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
2.设置启动完成属性
SystemProperties.set("sys.boot_completed", "1");//该属性在init.rc中有对应的action,如下:
/system/core/rootdir/init.rc
on property:sys.boot_completed=1
bootchart stop
3.通过finishBooting函数,调用sendBootCompletedLocked来发送开机完成广播Intent.ACTION_LOCKED_BOOT_COMPLETED
sendBootCompletedLocked(/frameworks/base/services/core/java/com/android/server/am/UserController.java)
4.finishUserUnlocking()发送SYSTEM_USER_UNLOCK_MSG消息给AMS,然后调用mUserController.finishUserUnlocked()函数,最后调用finishUserUnlockedCompleted()函数发送开机完成广播,如下:
final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
mInjector.broadcastIntentLocked(bootIntent, null, new IIntentReceiver.Stub() {
到此启动结束;
调用Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
打印log如下:
01-01 06:50:44.803 1579 1651 I ActivityManager: Finished processing BOOT_COMPLETED for u0
3.1 kernel启动
01-01 06:50:09.145 <6>[ 0.000000] [<0>][0, swapper]Booting Linux on physical CPU 0x0//启动kernel
3.2 init第一阶段
01-01 06:50:08.774 <14>[ 3.241877] [<1>][1, init]init: init first stage started!
01-01 06:50:08.800 <14>[ 4.436516] [<1>][1, init]init: Parsing file /init.zygote64_32.rc...//解析init.rc
01-01 06:50:08.805 <14>[ 6.536434] [<1>][1, init]init: starting service 'zygote'...//启动zygote服务
01-01 06:50:08.805 <14>[ 6.537098] [<1>][1, init]init: starting service 'zygote_secondary'...
3.3 init第二阶段
01-01 06:50:08.799 <14>[ 4.408592] [<1>][1, init]init: init second stage started!
3.4 初始化守护进程
3.5 启动Zygote AndroidRuntime
ALOGD(">>>>>> START %s uid %d <<<<<<\n",
className != NULL ? className : "(unknown)", getuid());
01-01 06:50:08.447 653 653 D AndroidRuntime: >>>>>> START com.android.internal.os.ZygoteInit uid 0 <<<<<<
01-01 06:50:08.477 653 653 I zygote : option[0]=-Xzygote
01-01 06:50:08.477 653 653 I zygote : option[1]=-Xusetombstonedtraces
01-01 06:50:08.478 653 653 I zygote : option[2]=exit
01-01 06:50:08.478 653 653 I zygote : option[3]=vfprintf
01-01 06:50:08.478 653 653 I zygote : option[4]=sensitiveThread
01-01 06:50:08.479 653 653 I zygote : option[5]=-verbose:gc
01-01 06:50:08.479 653 653 I zygote : option[6]=-Xms8m
01-01 06:50:08.479 653 653 I zygote : option[7]=-Xmx512m
01-01 06:50:08.479 653 653 I zygote : option[8]=-XX:HeapGrowthLimit=256m
01-01 06:50:08.480 653 653 I zygote : option[9]=-XX:HeapMinFree=512k
01-01 06:50:08.480 653 653 I zygote : option[10]=-XX:HeapMaxFree=8m
01-01 06:50:08.480 653 653 I zygote : option[11]=-XX:HeapTargetUtilization=0.75
01-01 06:50:08.481 653 653 I zygote : option[12]=-Xusejit:true
01-01 06:50:08.481 653 653 I zygote : option[13]=-Xjitsaveprofilinginfo
01-01 06:50:08.481 653 653 I zygote : option[14]=-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y
01-01 06:50:08.482 653 653 I zygote : option[15]=-Xlockprofthreshold:500
01-01 06:50:08.482 653 653 I zygote : option[16]=-Ximage-compiler-option
01-01 06:50:08.482 653 653 I zygote : option[17]=--runtime-arg
01-01 06:50:08.483 653 653 I zygote : option[18]=-Ximage-compiler-option
01-01 06:50:08.483 653 653 I zygote : option[19]=-Xms64m
01-01 06:50:08.483 653 653 I zygote : option[20]=-Ximage-compiler-option
01-01 06:50:08.484 653 653 I zygote : option[21]=--runtime-arg
01-01 06:50:08.484 653 653 I zygote : option[22]=-Ximage-compiler-option
01-01 06:50:08.484 653 653 I zygote : option[23]=-Xmx64m
01-01 06:50:08.485 653 653 I zygote : option[24]=-Ximage-compiler-option
01-01 06:50:08.485 653 653 I zygote : option[25]=--image-classes=/system/etc/preloaded-classes
01-01 06:50:08.485 653 653 I zygote : option[26]=-Ximage-compiler-option
01-01 06:50:08.486 653 653 I zygote : option[27]=--compiled-classes=/system/etc/compiled-classes
01-01 06:50:08.486 653 653 I zygote : option[28]=-Ximage-compiler-option
01-01 06:50:08.486 653 653 I zygote : option[29]=--dirty-image-objects=/system/etc/dirty-image-objects
01-01 06:50:08.487 653 653 I zygote : option[30]=-Xcompiler-option
01-01 06:50:08.487 653 653 I zygote : option[31]=--runtime-arg
01-01 06:50:08.487 653 653 I zygote : option[32]=-Xcompiler-option
01-01 06:50:08.488 653 653 I zygote : option[33]=-Xms64m
01-01 06:50:08.488 653 653 I zygote : option[34]=-Xcompiler-option
01-01 06:50:08.488 653 653 I zygote : option[35]=--runtime-arg
01-01 06:50:08.489 653 653 I zygote : option[36]=-Xcompiler-option
01-01 06:50:08.489 653 653 I zygote : option[37]=-Xmx512m
01-01 06:50:08.489 653 653 I zygote : option[38]=-Ximage-compiler-option
01-01 06:50:08.490 653 653 I zygote : option[39]=--instruction-set-variant=cortex-a53
01-01 06:50:08.490 653 653 I zygote : option[40]=-Xcompiler-option
01-01 06:50:08.490 653 653 I zygote : option[41]=--instruction-set-variant=cortex-a53
01-01 06:50:08.491 653 653 I zygote : option[42]=-Ximage-compiler-option
01-01 06:50:08.491 653 653 I zygote : option[43]=--instruction-set-features=default
01-01 06:50:08.491 653 653 I zygote : option[44]=-Xcompiler-option
01-01 06:50:08.492 653 653 I zygote : option[45]=--instruction-set-features=default
01-01 06:50:08.492 653 653 I zygote : option[46]=-Duser.locale=zh-CN
01-01 06:50:08.492 653 653 I zygote : option[47]=--cpu-abilist=armeabi-v7a,armeabi
01-01 06:50:08.493 653 653 I zygote : option[48]=-Xfingerprint:samsung/Phoenix/Phoenix:8.1.0/OPM1.171019.026/G6200ZCU0ARH3:userdebug/release-keys
Log.d(TAG, "begin preload");
01-01 06:50:09.677 652 652 D Zygote : begin preload
01-01 06:50:09.763 652 652 I Zygote : Preloading classes...
01-01 06:50:10.420 652 652 I Zygote : Preloading resources...
01-01 06:50:10.491 652 652 D Zygote : end preload
01-01 06:50:13.390 653 653 I Zygote : Lazily preloading resources.
01-01 06:50:13.390 653 653 D Zygote : begin preload
01-01 06:50:13.683 653 653 I Zygote : Preloading resources...
01-01 06:50:13.815 653 653 I Zygote : Preloading shared libraries...
Log.d(TAG, "end preload");
01-01 06:50:13.834 653 653 D Zygote : end preload
Log.i(TAG, "Accepting command socket connections");
01-01 06:50:09.665 653 653 I Zygote : Accepting command socket connections
3.6 启动SystemServer
startBootstrapServices()
traceBeginAndSlog("InitBeforeStartServices");//run()
01-01 06:50:10.667 1579 1579 I SystemServer: InitBeforeStartServices
01-01 06:50:10.668 1579 1579 W SystemServer: System clock is before 1970; setting to 1970.
01-01 06:50:10.668 1579 1579 W SystemServer: Timezone not set; setting to GMT.
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
01-01 06:50:10.672 1579 1579 I SystemServer: Entered the Android system server!
Slog.i(TAG, "Reading configuration...");//startBootstrapServices
01-01 06:50:10.786 1579 1579 I SystemServer: Reading configuration...
traceBeginAndSlog("StartInstaller");
01-01 06:50:10.787 1579 1579 I SystemServer: StartInstaller
01-01 06:50:10.789 1579 1579 D SystemServerTiming: StartInstaller took to complete: 2ms
traceBeginAndSlog("DeviceIdentifiersPolicyService");
01-01 06:50:10.789 1579 1579 I SystemServer: DeviceIdentifiersPolicyService
01-01 06:50:10.791 1579 1579 D SystemServerTiming: DeviceIdentifiersPolicyService took to complete: 1ms
traceBeginAndSlog("StartPowerManager");
01-01 06:50:10.946 1579 1579 I SystemServer: StartPowerManager
01-01 06:50:10.973 1579 1579 D SystemServerTiming: StartPowerManager took to complete: 26ms
traceBeginAndSlog("InitPowerManagement");
01-01 06:50:10.973 1579 1579 I SystemServer: InitPowerManagement
01-01 06:50:10.974 1579 1579 D SystemServerTiming: InitPowerManagement took to complete: 1ms
traceBeginAndSlog("StartRecoverySystemService");
01-01 06:50:10.975 1579 1579 I SystemServer: StartRecoverySystemService
01-01 06:50:10.976 1579 1579 D SystemServerTiming: StartRecoverySystemService took to complete: 1ms
traceBeginAndSlog("StartLightsService");
01-01 06:50:10.977 1579 1579 I SystemServer: StartLightsService
01-01 06:50:10.978 1579 1579 D SystemServerTiming: StartLightsService took to complete: 0ms
traceBeginAndSlog("StartDisplayManager");
01-01 06:50:10.979 1579 1579 I SystemServer: StartDisplayManager
01-01 06:50:10.980 1579 1579 D SystemServerTiming: StartDisplayManager took to complete: 1ms
traceBeginAndSlog("WaitForDisplay");
01-01 06:50:10.981 1579 1579 I SystemServer: WaitForDisplay
01-01 06:50:10.994 1579 1579 D SystemServerTiming: WaitForDisplay took to complete: 13ms
traceBeginAndSlog("StartPackageManagerService");
01-01 06:50:11.000 1579 1579 I SystemServer: StartPackageManagerService
01-01 06:50:13.213 1579 1579 D SystemServerTiming: StartPackageManagerService took to complete: 2213ms
traceBeginAndSlog("StartOtaDexOptService");
01-01 06:50:13.213 1579 1579 I SystemServer: StartOtaDexOptService
01-01 06:50:13.215 1579 1579 D SystemServerTiming: StartOtaDexOptService took to complete: 2ms
traceBeginAndSlog("StartUserManagerService");
01-01 06:50:13.215 1579 1579 I SystemServer: StartUserManagerService
01-01 06:50:13.216 1579 1579 D SystemServerTiming: StartUserManagerService took to complete: 1ms
traceBeginAndSlog("InitAttributerCache");
01-01 06:50:13.217 1579 1579 I SystemServer: InitAttributerCache
01-01 06:50:13.217 1579 1579 D SystemServerTiming: InitAttributerCache took to complete: 0ms
traceBeginAndSlog("SetSystemProcess");
01-01 06:50:13.217 1579 1579 I SystemServer: SetSystemProcess
01-01 06:50:13.225 1579 1579 D SystemServerTiming: SetSystemProcess took to complete: 7ms
traceBeginAndSlog("StartOverlayManagerService");
01-01 06:50:13.227 1579 1579 I SystemServer: StartOverlayManagerService
01-01 06:50:13.234 1579 1579 D SystemServerTiming: StartOverlayManagerService took to complete: 7ms
startCoreServices()
traceBeginAndSlog("StartDropBoxManager");
01-01 06:50:13.235 1579 1579 I SystemServer: StartDropBoxManager
01-01 06:50:13.237 1579 1579 D SystemServerTiming: StartDropBoxManager took to complete: 2ms
traceBeginAndSlog("StartBatteryService");
01-01 06:50:13.237 1579 1579 I SystemServer: StartBatteryService
01-01 06:50:13.243 1579 1579 D SystemServerTiming: StartBatteryService took to complete: 6ms
traceBeginAndSlog("StartUsageService");
01-01 06:50:13.243 1579 1579 I SystemServer: StartUsageService
01-01 06:50:13.255 1579 1579 D SystemServerTiming: StartUsageService took to complete: 10ms
traceBeginAndSlog("StartWebViewUpdateService");
01-01 06:50:13.255 1579 1579 I SystemServer: StartWebViewUpdateService
01-01 06:50:13.263 1579 1579 D SystemServerTiming: StartWebViewUpdateService took to complete: 7ms
startOtherServices()
Slog.i(TAG, SECONDARY_ZYGOTE_PRELOAD);
01-01 06:50:13.367 1579 1648 I SystemServer: SecondaryZygotePreload
01-01 06:50:13.835 1579 1648 D SystemServerTimingAsync: SecondaryZygotePreload took to complete: 467ms
01-01 06:50:13.835 1579 1648 D SystemServerInitThreadPool: Finished executing SecondaryZygotePreload
traceBeginAndSlog("InstallSystemProviders");
01-01 06:50:13.418 1579 1579 I SystemServer: InstallSystemProviders
01-01 06:50:13.542 1579 1579 D SystemServerTiming: InstallSystemProviders took to complete: 124ms
traceBeginAndSlog("InitWatchdog");
01-01 06:50:13.563 1579 1579 I SystemServer: InitWatchdog
01-01 06:50:13.564 1579 1579 D SystemServerTiming: InitWatchdog took to complete: 0ms
3.8 启动AMS
Slog.d("AppOps", "AppOpsService published");
01-01 06:50:10.945 1579 1579 D AppOps : AppOpsService published
Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
01-01 06:50:10.819 1579 1579 I ActivityManager: Memory class: 256
traceBeginAndSlog("StartActivityManager");
01-01 06:50:10.791 1579 1579 I SystemServer: StartActivityManager
Slog.i(TAG, "System now ready");///frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java::systemReady()
01-01 06:50:19.989 1579 1579 I ActivityManager: System now ready
traceLog.traceBegin("PhaseActivityManagerReady");
01-01 06:50:20.515 1579 1579 D SystemServerTiming: PhaseActivityManagerReady took to complete: 528ms
3.9 Launcher
01-01 06:50:24.116 1579 1579 I ActivityManager: Start proc 3212:com.android.launcher3/u0a12 for service com.android.launcher3/.notification.NotificationListener
01-01 06:50:24.432 1579 1618 I am_create_activity: [0,166559440,4,com.android.launcher3/.Launcher,android.intent.action.MAIN,NULL,NULL,268435712]
3.10 开机启动完成
01-01 06:50:22.702 <14>[ 22.581470] [<1>][1, init]init: processing action (sys.boot_completed=1) from (/init.rc:740)//启动完成
Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);//finishUserUnlockedCompleted()//main log
01-01 06:50:25.437 1579 3157 I ActivityManager: Sending BOOT_COMPLETE user #0
Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
01-01 06:50:44.803 1579 1651 I ActivityManager: Finished processing BOOT_COMPLETED for u0//main log