Android10系统启动概述

Android10系统启动大纲,后面有时间将会详细分析每一个启动阶段

发布日期 2020-02-08

本文总结一下android10系统启动的整个流程,作为系统启动系列文章的开篇大纲

系统启动相关文章列表
Android10系统启动之init进程详解
Android10系统启动之Zygote进程详解
Android10系统启动之SystemServer进程详解
Android10系统启动之AMS服务启动详解
Android10系统启动之Launcher启动详解/

首先用两张图看一下整体的启动流程,我们主要从init阶段开始分析启动的流程.

因为android系统底层是基于Linux Kernel, 所以当Kernel启动后会创建init进程,init进程是Linux系统中用户空间的第一个进程(pid=1)。可以说android中的所有其他进程的共同祖先都是init

一 init进程启动

Android 10 系统中init入口函数从init.cpp 挪到了main.cpp 源码路径 system/core/init/main.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
int main(int argc, char** argv) {
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }
 
   //参数个数大于1时,执行下面的操作
    if (argc > 1) {
        //参数为subcontext,启动日志系统,
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap function_map;
            return SubcontextMain(argc, argv, &function_map);
        }
 
      //参数为 selinux_setup, 启动Selinux安全策略
        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }
      //参数为 second_stage, init进程第二阶段
        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }
    //init进程第一阶段
    return FirstStageMain(argc, argv);
}

二 zygote进程启动

Init进程启动后,通过解析init.rc 文件来启动zygote 在/system/core/rootdir/init.rc中,通过下面的语句import zygote的rc文件,其中${ro.zygote} 是动态的,目前使用的最多的是zygote64_32。

1
import /init.${ro.zygote}.rc

当zygote进程启动后便会执行到frameworks/base/cmds/app_process/app_main.cpp的main方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(int argc, char* const argv[]){
    .........
     if (!niceName.isEmpty()) {
          runtime.setArgv0(niceName.string(), true /* setProcName */);
      }
      if (zygote) {
      // 启动 ZygoteInit.java 正式进入java世界
         runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
      } else if (className) {
         runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
      } else {
         fprintf(stderr, "Error: no class name or --zygote supplied.\n");
         app_usage();
         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
      }
}

当zygote为 true时启动ZygoteInit当为false时启动RuntimeInit

三 SystemServer进程启动

Zygote fork的第一个进程就是SystemServer,进程名为 system_server,system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等80多个核心系统服务,都运行在system_server这个进程中。在ZygoteInit的forkSystemServer方法中fork出SystemServer进程

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
private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
    ......
    ZygoteArguments parsedArgs = null;
    int pid;
    try {
        parsedArgs = new ZygoteArguments(args);
        Zygote.applyDebuggerSystemProperty(parsedArgs);
        Zygote.applyInvokeWithSystemProperty(parsedArgs);
        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }
 
    //进入子进程system_server
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            //等待第二个Zygote创建完成
            waitForSecondaryZygote(socketName);  
        }
 
        // fork时会copy socket,Zygote原有的socket需要关闭
        zygoteServer.closeServerSocket();
        // 处理system server相关工作
        return handleSystemServerProcess(parsedArgs);
    }
    return null;
}

四 AMS服务启动

systemServer进程启动后会初始化系统中的各种服务包括ActivityManangerService,在AMS就绪后会启动系统桌面从而完成系统的整个启动流程

1
2
3
4
5
6
7
public void systemReady(final Runnable goingCallback, TimingsTraceLog 
traceLog) {
    ...
    //启动Home桌面
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    ...
}

后续有时间将会分章节详细分析各个阶段的启动流程.