从 Init 到 Zygote 到 SystemServer 的启动流程梳理

内容来自:

Android系统启动分析(Init->Zygote->SystemServer->Home activity):

https://www.cnblogs.com/lao-liang/p/5067312.html

图解Android - Zygote, System Server 启动分析:

https://www.cnblogs.com/samchen2009/p/3294713.html

(连载)Android 8.0 : 系统启动流程之init进程(一)

https://www.jianshu.com/p/769c58285c22

(连载)Android 8.0 : Android系统启动流程之zygote进程(一)

https://www.jianshu.com/p/42adb1eda320



以下内容均为上述链接文章内容的总结和摘要:

Init:

整个Android系统的启动分为Linux Kernel的启动和Android系统的启动。Linux Kernel启动起来后,然后运行第一个用户程序,在Android中就是init程序。

init 是所有Linux程序的起点,而Zygote于Android,是所有java程序的'孵化池。

init 是 zygote的父进程, 而system_server和其他所有的com.xxx结尾的应用程序都是从zygote fork 而来。


Zygote :

zygote本身是一个Native的应用程序,与驱动、内核等无关。它是由init进程根据init.rc文件中的配置创建的。zygote最初的名字叫“app_process”,这个名字是在Android.mk文件中指定的。在运行中,app_process通过linux下的pctrl系统调用将自己的名字换成了zygote。

在Java中,我们知道不同的虚拟机实例会为不同的应用分配不同的内存。假如Android应用应该尽可能快地启动,但如果Android系统为每一个应用启动不同的Dalvik虚拟机实例,就会消耗大量的内存以及时间。因此,为了克服这个问题,Android系统创造了”zygote”。zygote让Dalvik虚拟机共享代码、低内存占用以及最小的启动时间成为可能。

zygote进程由init通过fork而来,在init.rc中,搜索一下“start zygote”,可看到:

# system/core/rootdir/init.rc
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=unsupported
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    start zygote
    start zygote_secondary

zygote-start 是在 on late-init 中触发的:

# system/core/rootdir/init.rc
# Mount filesystems and start core system services.
on late-init
    ......
    # Now we can start zygote for devices with file based encryption
    trigger zygote-start
    ......

late-init 在哪儿触发的呢?在init进程的最后,会加入 late-init 的 trigger:

    if (bootmode == "charger") {
        am.QueueEventTrigger("charger");
    } else {
        am.QueueEventTrigger("late-init");
    }

由此分析,zygote的触发是在init进程最后。.

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

//frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    ......
    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    ......
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    }
    ......
}

在 com/android/internal/os/ZygoteInit.java 的 main 函数中,启动了SystemServer.

//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
......
if (startSystemServer) {
    // gh 1.1 - 1.2
    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

    // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
    // child (system_server) process.
    if (r != null) {
        r.run();
        return;
    }
}
}

// gh 1.2
private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) { 
......
/* For child process */
if (pid == 0) {
    if (hasSecondZygote(abiList)) {
        waitForSecondaryZygote(socketName);
    }

    zygoteServer.closeServerSocket();
    // gh 1.2-1.3
    return handleSystemServerProcess(parsedArgs);
}
......
}

//gh 1.3
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs){
......
/*
 * Pass the remaining arguments to SystemServer.
 */
// 1.3 - 1.4
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
.......
}

// gh 1.4
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
    if (RuntimeInit.DEBUG) {
        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    RuntimeInit.redirectLogStreams();//重定向log

    RuntimeInit.commonInit();//初始化运行环境

    ZygoteInit.nativeZygoteInit();//启动binder线程池
    // gh 1.4 - 1.5
    //调用应用程序的入口函数
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
// gh 1.5
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
......
    // Remaining arguments are passed to the start class's static main
    // gh 1.5 -1.6
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}


// gh 1.6
private static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    // 解析类名
    Class<?> cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

    Method m;
    try {
        //gh 1.6 - 1.7
        //解析main方法,然会就会调用SystemServer的main函数
        m = cl.getMethod("main", new Class[] { String[].class });
    }
......
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值