整个Android系统的启动分为Linux Kernel的启动和Android系统的启动。Linux Kernel启动起来后,然后运行第一个用户程序,在Android中就是init程序。
init是linux系统中用户空间的第一个进程。由于Android是基于linux内核的,所以init也是Android系统中用户空间的第一个进程,它的进程号是1。

init进程的入口文件在system/core/init/init.cpp中,由于init是命令行程序,所以分析init.cpp首先应从main函数开始:
1 | int main(int argc, char** argv) { // 入口函数main |
init的主要职责在于:
- 创建文件系统目录并挂载相关的文件系统
1 | mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); |
- 初始化属性,提供property service(属性服务)管理Android系统中的属性
1 | property_init();// 初始化属性域 --> 定义于system/core/init/Property_service.cpp |
处理配置文件命令(主要是init.rc脚本文件)
1
2
3
4
5
6/* 解析init.rc */
Parser& parser = Parser::GetInstance();
parser.AddSectionParser("service",std::make_unique<ServiceParser>());
parser.AddSectionParser("on", std::make_unique<ActionParser>());
parser.AddSectionParser("import", std::make_unique<ImportParser>());
parser.ParseConfig("/init.rc");init.rc是一个配置文件,内部由Android初始化语言编写(Android Init Language)编写的脚本,主要包含五种类型语句:Action、Command、Service、Option和Import,在分析代码的过程中我们会详细介绍。
init.rc的配置代码在:system/core/rootdir/init.rc 中
init.rc文件是在init进程启动后执行的启动脚本,文件中记录着init进程需执行的操作。
init.rc文件大致分为两大部分,一部分是以“on”关键字开头的动作列表(action list):
1
2
3
4
5on early-init // Action类型语句
# Set init and its forked children's oom_adj. // #:注释符号
write /proc/1/oom_score_adj -1000
... ...
start ueventd Action类型语句格式:
1
2
3on <trigger> [&& <trigger>]* // 设置触发器
<command>
<command> // 动作触发之后要执行的命令 另一部分是以“service”关键字开头的服务列表(service list): 如 Zygote
1
2
3
4
5
6
7
8service ueventd /sbin/ueventd
class core
critical
seclabel u:r:ueventd:s0
service dvbserver /vendor/bin/dvbserver
user root
group rootService类型语句格式:
1
2
3
4service <name> <pathname> [ <argument> ]* // <service的名字><执行程序路径><传递参数>
<option> // option是service的修饰词,影响什么时候、如何启动services
<option>
...借助系统环境变量或Linux命令,动作列表用于创建所需目录,以及为某些特定文件指定权限,而服务列表用来记录init进程需要启动的一些子进程。如上面代码所示,service关键字后的第一个字符串表示服务(子进程)的名称,第二个字符串表示服务的执行路径。
值得一提的是在Android 7.0中对init.rc文件进行了拆分,每个服务一个rc文件。我们要分析的zygote服务的启动脚本则在init.zygoteXX.rc中定义。
在init.rc的import段我们看到如下代码:
1 | import /init.${ro.zygote}.rc |
init.zygote64.rc的代码如下所示:
1 | service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server |
可以看到zygote的class是main, 它是在on nonencrypted时被启动的,如下:
1 | on nonencrypted |
Init.cpp的main函数分析完毕,init进程已经启动完成,一些重要的服务如core服务和main服务也都启动起来,并启动了zygote(/system/bin/app_process64)进程,zygote初始化时会创建虚拟机,启动systemserver等。