Android_系统启动流程解析

本文代码基于Android8.0

1.1 概述

Android系统是基于Linux Kernel而创建的一个世界,当Linux Kernel启动运行后,它就会开启Android世界。

第一个被启动的是Init进程,因此Init进程是整个Android世界(用户空间)的祖先,天字一号的存在。

第二个被启动的是Zygote,Zygote由Init进程裂变而来,Zygote启动后会开启Android的java世界,因此Zygote是Android系统中java世界的祖先。

第三个被启动的是SystemServer,由Zygote中fork出SystemServer,SystemServer中会启动一系列Android服务,从此Android世界的骨架被建立起来了

下面从这三个方面进行分析

1.2 Init进程

\system\core\init\init.cpp

1
2
3
4
5
6
7
8
9
int main(int argc, char** argv) {
......
//开启属性服务
start_property_service();
......
//解析init.rc
parser.ParseConfig("/init.rc");
......
}

Init进程解析”init.rc”文件

\system\core\rootdir\init.rc

1
2
//导入zygote.rc
import /init.${ro.zygote}.rc

由以上代码看出Zygote进程启动rc在zygote.rc文件中

\system\core\rootdir\init.zygote64.rc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//init进程解析运行下面rc后,则开启Zygote进程
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
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

1.3 Zygote解析

Zygote最初的名字叫”app_process”,实在Android.mk文件中指定的,在运行过程中app_process通过Linux下的pctrl系统调用将自己的名字换成了”zygote”,所以我们通过ps命令看到的进程名是”zygote”。

Zygote的原型app_process对应的源文件是app_main.cpp

\frameworks\base\cmds\app_process\app_main.cpp

1
2
3
4
5
6
7
8
9
int main(int argc, char* const argv[]){
......
//创建AppRuntime,并设置一系列设置参数(className等)
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
......
//调用start方法,其实Zygote的主要工作在APPRuntime::start()方法中
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
......
}

\frameworks\base\core\jni\AndroidRuntime.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
........
//启动jvm
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
.......
//为虚拟机注册一些JNI函数
if (startReg(env) < 0) {
return;
}
......
//启动java世界,startClass指向\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
env->CallStaticVoidMethod(startClass, startMeth, strArray);
......
}

\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String argv[]) {
......
//创建并注册mServerSocket
zygoteServer.registerServerSocket(socketName);
......
//预加载系统资源,(class,resources等)此处可做开机时间优化操作
preload(bootTimingsTraceLog);
......
//创建SystemServer
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
......
//在fork后,selectLoop会在Zygote中永远运行,等待处理客户链接和请求
//客户请求由ZygoteConnection的runOnce()来处理
caller = zygoteServer.runSelectLoop(abiList);
......
}

上面的代码描述了Zygote再启动的时候的主要工作,那么接下来我们分析这些工作的内容,以帮助我们更好的了解系统的启动过程。

1.注册mServerSocket

2.预加载资源

3.创建SystemServer

4.运行ZygoteServer,等待处理请求

在这里重点分析下SystemServer的启动吧,其他的相对比较直观,可以通过源码了解。

1.4SystemServer解析

SystemServer进程名称为system_server,作为Zygote的第一个儿子,其重要性不言而喻。

由上面一节可以了解到,SS是由Zygote通过Zygote.forkSystemServer()方法fork出来的,继续往下跟代码,就会发现最终调用了native函数nativeForkSystemServer()

\frameworks\base\core\jni\com_android_internal_os_Zygote.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
//调用了ForkAndSpecializeCommon()
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL, NULL);
if (pid > 0) {
......
}
}

// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint runtime_flags, jobjectArray javaRlimits,
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
jintArray fdsToIgnore,
jstring instructionSet, jstring dataDir) {
SetSigChldHandler();//设置信号处理,如果死去的是SS进程,则Zygote自杀,SS和其老爹生死与共

......
pid_t pid = fork();//fork子进程
......

if (pid == 0) {
......
//根据传入的参数对上面fork出来的子进程做一系列处理,例如设置进程名,设置用户id,组id等
......
}
//在这里我们会发现有很多地方调用了RuntimeAbort(),主要是因为各种原因导致需要重启Zygote,详情可自行了解
}

通过上面代码,了解了SS的诞生,SS和Zygote是生死与共的父子关系,SS必然任重道远,那么SS的主要任务究竟是什么,继续往下看

\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
private static boolean startSystemServer(String abiList, String socketName){
......

/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);

......

/* For child process */
if (pid == 0) {
......
//SS已经被启动,因此关闭Socket
zygoteServer.closeServerSocket();
//重点调用了handleSystemServerProcess,这个方法中主要体现SS进程的功能
return handleSystemServerProcess(parsedArgs);
}

......
}

private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
// 设置umask到0077,所以新的文件和目录将默认为所有者权限。
Os.umask(S_IRWXG | S_IRWXO);
......
//配置参数
......
//创建类加载器
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
//将类加载器设置到当前线程
Thread.currentThread().setContextClassLoader(cl);
}
......
//将剩余的参数传递给SystemServer
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
......
//常规初始化
RuntimeInit.commonInit();
//调用native层的初始化
ZygoteInit.nativeZygoteInit();
//调用应用层初始化
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

上面代码中可清晰的看出,SS被启动后handleSystemServerProcess()的一系列调用,重点重两个方面来看,即:1.native层初始化,2.应用层初始化

1.4.1 native层初始化

先看看ZygoteInit.nativeZygoteInit()的调用,他在AndroidRuntime.cpp中

\frameworks\base\core\jni\AndroidRuntime.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
//就一句调用,那么gCurRuntime是干什么的呢?
//在“1.3 Zygote解析”中app_process的main()函数中定义runtime,它就是这里的gCurRuntime
//定义gCurRuntime为全局变量
//static AndroidRuntime* gCurRuntime = NULL;

//AndroidRuntime::AndroidRuntime(){
// //gCurRuntime被设为自己
// gCurRuntime = this;
//}*/

gCurRuntime->onZygoteInit();
}

由于SS是Zygote fork出来的,因此它也拥有Zygote进程中定义的这个gCurRuntime,也就是AndroidRuntime对象。那么它的onZygoteInit()主要干了什么呢?

\frameworks\base\cmds\app_process\app_main.cpp

1
2
3
4
5
6
7
  virtual void onZygoteInit()
{
//和binder有关
sp<ProcessState> proc = ProcessState::self();
//启动一个线程用于binder通信
proc->startThreadPool();
}

nativeZygoteInit的调用主要是建立binder通信的联系,这样SS就可以使用binder了

1.4.2 应用层初始化

下面我们来看看applicationInit()方法

\frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
......

//这里找到com.android.server.SystemServer类的main()函数
return findStaticMain(args.startClass, args.startArgs, classLoader);
}

private static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
......
//返回一个对象,并且传入Method和argv两个参数,该对象的类型是Runnable
return new MethodAndArgsCaller(m, argv);
}

static class MethodAndArgsCaller implements Runnable {
public void run() {
//最终启动了com.android.server.SystemServer类的main()函数
mMethod.invoke(null, new Object[] { mArgs });
}
}

Zygote分裂产生的SS,最终就是为了调用com.android.server.SystemServer类的main()函数,相信走到这里就应该松一口气了,因为SystemServer还是很熟悉滴,那么直接上代码

\frameworks\base\services\java\com\android\server\SystemServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void main(String[] args) {
//调用SystemServer的run()方法
new SystemServer().run();
}

private void run() {
......
// 加载libandroid_servers.so库,该so库的代码路径如下
//\frameworks\base\services\core\jni\com_android_server_SystemServer.cpp
System.loadLibrary("android_servers");

......
// 初始化系统Context变量
createSystemContext();

// 创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);

......
//加载系统中的各种服务,可自行阅读源码了解
startBootstrapServices();
startCoreServices();
startOtherServices();
}

到了这里我们就打通了系统启动的底层的所有的调用流程,下面以函数调用时序图作为总结,以方便代码查阅

Android启动流程01