本文首发地址 https://h89.cn/archives/298.html
最新更新地址 https://gitee.com/chenjim/chenjimblog

本文主要结合日志和代码看安卓 14 中 Zygote 启动相关流程

日志抓取

先抓一份开机日志
adb reboot && adb wait-for-device shell logcat -b all > all.log
过滤出 zygote 相关日志
cat all.log | grep -i Zygote > all.Zygote.log
以上完整日志文件 https://gitee.com/chenjim/ResData/tree/master/boot.01.log
我们看一下 日志文件 all.Zygote.log , 部分日志如下

07-01 21:43:43.516     0     0 I init    : Added '/system/etc/init/hw/init.zygote64.rc' to import list
07-01 21:43:43.516     0     0 I init    : Parsing file /system/etc/init/hw/init.zygote64.rc...
07-01 21:43:45.841     0     0 I init    : processing action (ro.crypto.state=encrypted && ro.crypto.type=file && zygote-start) from (/system/etc/init/hw/init.rc:1090)
07-01 21:43:45.880     0     0 I init    : starting service 'zygote'...
07-01 21:43:45.881     0     0 I init    : Created socket '/dev/socket/zygote', mode 660, user 0, group 1000
07-01 21:43:46.329   282   282 D AndroidRuntime: >>>>>> START com.android.internal.os.ZygoteInit uid 0 <<<<<<
07-01 21:43:46.422     0     0 I init    : service 'zygote' requested start, but it is already running (flags: 4)
07-01 21:43:46.527   282   282 I zygote64: option[0]=-Xzygote
07-01 21:43:47.411   282   282 D Zygote  : begin preload
07-01 21:43:47.414   282   282 I Zygote  : Calling ZygoteHooks.beginPreload()
07-01 21:43:47.523   282   282 V Zygote64Timing: BeginPreload took to complete: 112ms
07-01 21:43:47.524   282   282 I Zygote  : Preloading classes...
07-01 21:43:47.745   283   283 V Zygote32Timing: PostZygoteInitGC took to complete: 330ms
07-01 21:43:47.745   283   283 V Zygote32Timing: ZygoteInit took to complete: 377ms
07-01 21:43:47.748   283   283 I Zygote  : Accepting command socket connections
07-01 21:43:48.888   282   282 I Zygote  : ...preloaded 17308 classes in 1364ms.  
07-01 21:43:48.897   282   282 I Zygote  : Preloading resources...  
07-01 21:43:48.933   282   282 V Zygote64Timing: PreloadResources took to complete: 36ms
07-01 21:43:48.939   282   282 I Zygote  : Preloading shared libraries...
07-01 21:43:48.942   282   282 I Zygote  : Called ZygoteHooks.endPreload()
07-01 21:43:48.946   282   282 D Zygote  : end preload
07-01 21:43:48.946   282   282 V Zygote64Timing: ZygotePreload took to complete: 1535ms
07-01 21:43:49.179   282   282 V Zygote64Timing: PostZygoteInitGC took to complete: 233ms
07-01 21:43:49.179   282   282 V Zygote64Timing: ZygoteInit took to complete: 1810ms
07-01 21:43:49.437   282   282 D Zygote  : Forked child process 481
07-01 21:43:49.437   282   282 I Zygote  : System server process 481 has been created
07-01 21:43:49.437   282   282 I Zygote  : Accepting command socket connections
07-01 21:43:51.624   481   540 D SystemServerTimingAsync: InitThreadPoolExec:SecondaryZygotePreload
07-01 21:43:51.624   481   540 D SystemServerInitThreadPool: Started executing SecondaryZygotePreload
07-01 21:43:51.625   481   540 I SystemServer: SecondaryZygotePreload
07-01 21:43:51.627   283   283 I Zygote  : Lazily preloading resources.
07-01 21:43:53.572   481   540 D SystemServerInitThreadPool: Finished executing SecondaryZygotePreload
07-01 21:43:54.078   282   282 I Zygote  : Entering forkRepeatedly native zygote loop
07-01 21:43:54.081   282   282 D Zygote  : Forked child process 690

结合日志与源码分析

通过上面日志看到,首先通过 init.zygote64.rc 启动 app_process64

那 app_process64 在哪呢,参见如下

# frameworks/base/cmds/app_process/Android.bp
cc_binary {
    name: "app_process",
    srcs: ["app_main.cpp"],
}

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));
    // ...
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    }
}

class AppRuntime : public AndroidRuntime { }

// ./frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
    // 启动虚拟机
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    // ...
    // 启动 ./frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
}
//./framework/base/core/java/com/android/internal/os/ZygoteInit.java  
public static void main(String[] argv) {
    if (!enableLazyPreload) {
        // 加载资源 
        preload(bootTimingsTraceLog);
    }
    // ... 
    // new ZygoteServer 构造中 通过 Zygote.createManagedSocketFromInitSocket 创建 LocalServerSocket 
    zygoteServer = new ZygoteServer(isPrimaryZygote);
    if (startSystemServer) {
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
        if (r != null) {
            r.run();
            return;
        }
    }
    // 创建 sokect server 等待连接
    caller = zygoteServer.runSelectLoop(abiList);
}
private static Runnable forkSystemServer(String abiList, String socketName,
    ZygoteServer zygoteServer) {
        // ...
        pid = Zygote.forkSystemServer(
        parsedArgs.mUid, parsedArgs.mGid,
        parsedArgs.mGids,
        parsedArgs.mRuntimeFlags,
        null,
        parsedArgs.mPermittedCapabilities,
        parsedArgs.mEffectiveCapabilities);
        // ...
}
// ./framework/base/core/java/com/android/internal/os/Zygote.java
 static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        ZygoteHooks.preFork();

        int pid = nativeForkSystemServer(
                uid, gid, gids, runtimeFlags, rlimits,
                permittedCapabilities, effectiveCapabilities);

        // Set the Java Language thread priority to the default value for new apps.
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);

        ZygoteHooks.postForkCommon();
        return pid;
    }
// framework/base/core/jni/com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(...){
    pid_t pid = zygote::ForkCommon(env, true,
                                    fds_to_close,
                                    fds_to_ignore,
                                    true);
    if (pid == 0) {
        // System server prcoess does not need data isolation so no need to
        // know pkg_data_info_list.
        SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,
                        effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
                        false, nullptr, nullptr, /* is_top_app= */ false,
                        /* pkg_data_info_list */ nullptr,
                        /* allowlisted_data_info_list */ nullptr, false, false);
    } 
}
//./framework/base/core/jni/com_android_internal_os_Zygote.cpp 
pid_t zygote::ForkCommon(...){
     pid_t pid = fork();
    if (pid == 0) {
        if (is_priority_fork) {
            setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
        } else {
            setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
        }
    }
     return pid;
}

systemServer zygote创建时序图

通过以上分析,SystemServer 创建对应时序图如下

sequenceDiagram init.zygote64.rc ->>+ app_process.cpp : service zygote ; app_process.cpp ->>+ AndroidRuntime.cpp : start(...); AndroidRuntime.cpp ->>+ AndroidRuntime.cpp : startVm(...); AndroidRuntime.cpp ->>+ AndroidRuntime.cpp : startReg(...); AndroidRuntime.cpp ->>+ ZygoteInit.java : main(...); ZygoteInit.java ->>+ ZygoteInit.java : preload(...); ZygoteInit.java ->>+ ZygoteInit.java : forkSystemServer(...); ZygoteInit.java ->>+ Zygote.java : forkSystemServer(...); Zygote.java ->>+ os_Zygote.cpp : nativeForkSystemServer(...); os_Zygote.cpp ->>+ os_Zygote.cpp : zygote::ForkCommon(...); os_Zygote.cpp ->>+ os_Zygote.cpp : SpecializeCommon(...); ZygoteInit.java ->>+ ZygoteServer.java : new ZygoteServer(...); ZygoteServer.java ->>+ Zygote.java : createManagedSocketFromInitSocket(...); ZygoteInit.java ->>+ ZygoteServer.java : runSelectLoop(...);

若显示异常,可以查看图片 https://pic.chenjim.com/202407021035022.png-blog

一般应用 zygote 创建时序图

如果是 system server 以外的进程,会稍微有些不同,时序图如下

sequenceDiagram ZygoteServer.java ->>+ ZygoteServer.java : runSelectLoop(...); ZygoteServer.java ->>+ ZygoteConnection.java : processCommand(...); ZygoteConnection.java ->>+ Zygote.java : forkSimpleApps(...); Zygote.java ->>+ ZygoteCommandBuffer.java : forkRepeatedly(...); ZygoteCommandBuffer.java ->>+ ZygoteCommandBuffer.cpp : nativeForkRepeatedly(...); ZygoteCommandBuffer.cpp ->>+ os_Zygote.cpp : zygote::forkApp(...); os_Zygote.cpp ->>+ os_Zygote.cpp : zygote::ForkCommon(...);

若显示异常,可以查看图片 https://pic.chenjim.com/202407022321535.png-blog

向 zygote socket 发送数据时序图

向 zygote socket server 发送数据的时序是怎样的呢,如下图所示

sequenceDiagram ActivityManagerService.java -->>+ ActivityManagerService.java : startProcessLocked(...); ActivityManagerService.java -->>+ ProcessList.java : startProcessLocked(...); ProcessList.java -->>+ ProcessList.java : handleProcessStart(...); ProcessList.java -->>+ ProcessList.java : startProcess(...); ProcessList.java ->>+ Process.java : start(...); Process.java ->>+ ZygoteProcess.java : start(...); ZygoteProcess.java -->>+ ZygoteProcess.java : startViaZygote(...); ZygoteProcess.java -->>+ ZygoteProcess.java : zygoteSendArgsAndGetResult(...); ZygoteProcess.java -->>+ ZygoteProcess.java : attemptZygoteSendArgsAndGetResult(...);

若显示异常,可以查看图片 https://pic.chenjim.com/202407031312243.png-blog


日志中 481 是 system server 进程,690 是 systemui 进程,后续会进一步分析相关流程


相关链接


本文链接:安卓14中Zygote初始化流程及源码分析 - https://h89.cn/archives/298.html

版权声明:原创文章 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接和本声明。

标签: zygote

已有 2 条评论

  1. 怎么收藏这篇文章?

  2. 博主真是太厉害了!!!

添加新评论