Android 15 r17 Init 与 Zygote 启动流程

Android 15 r17 Init 与 Zygote 启动流程整理

目标:基于 AOSP Android 15 android-15.0.0_r17,梳理从 Linux Kernel 拉起 init,到 init 解析 .rc 并启动 zygote,再到 Zygote 进入 Java 层、预加载、fork system_server、监听应用孵化请求的主干流程。

重点涉及类:ZygoteInitZygoteZygoteServerZygoteConnectionRuntimeInitAndroidRuntimeSystemServer,以及 init 相关 Native 代码和 .rc 配置。


1. 参考源码范围

本文按以下 AOSP tag 组织:

  • Android 15 r17:android-15.0.0_r17
  • system/core/init/main.cpp
  • system/core/init/first_stage_init.cpp
  • system/core/init/selinux.cpp
  • system/core/init/init.cpp
  • system/core/rootdir/init.rc
  • system/core/rootdir/init.zygote*.rc
  • frameworks/base/cmds/app_process/app_main.cpp
  • frameworks/base/core/jni/AndroidRuntime.cpp
  • frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
  • frameworks/base/core/java/com/android/internal/os/Zygote.java
  • frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
  • frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
  • frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
  • frameworks/base/services/java/com/android/server/SystemServer.java

frameworks/base/services/core/java/com/android/server/am/ProcessList.java

final String entryPoint = "android.app.ActivityThread";

建议本地校验源码:

https://blog.csdn.net/Railshiqian/article/details/120541909?spm=1011.2415.3001.5331

2. 总览时序

text 复制代码
Bootloader
  └─ Linux Kernel
      └─ 启动用户空间第一个进程 init,PID = 1
          ├─ FirstStageMain:第一阶段 init,挂载基础目录、first stage mount
          ├─ SetupSelinux:加载并切换 SELinux 策略
          └─ SecondStageMain:第二阶段 init
              ├─ 初始化属性服务、信号处理、epoll
              ├─ 解析 /system/etc/init、/vendor/etc/init 等 rc
              ├─ import /init.${ro.zygote}.rc
              └─ class_start main 后启动 zygote service
                    └─ /system/bin/app_process64 ... --zygote --start-system-server
                        └─ app_main.cpp
                            └─ AndroidRuntime::start("com.android.internal.os.ZygoteInit", ...)
                                └─ ZygoteInit.main()
                                    ├─ 创建 ZygoteServer / server socket
                                    ├─ preload classes/resources/native libraries
                                    ├─ forkSystemServer()
                                    │   └─ SystemServer.main()
                                    └─ zygoteServer.runSelectLoop()
                                        └─ 接收 AMS/ProcessList 请求,fork app 进程

3. init 进程启动阶段

3.1 init 入口:main.cpp

init 是 Android 用户空间的第一个关键进程。Android 15 的 system/core/init/main.cpp 按启动参数分派到不同阶段:

cpp 复制代码
int main(int argc, char** argv) {
    setpriority(PRIO_PROCESS, 0, -20);

    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }

    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
            return SubcontextMain(argc, argv, &function_map);
        }
        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }
        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }

    return FirstStageMain(argc, argv);
}

主流程可以理解为:

  1. Kernel 首次执行 /init,无 second_stage 参数,进入 FirstStageMain()
  2. 第一阶段完成必要挂载后,通过 execv() 重新执行 /system/bin/init selinux_setup,仍保持 PID 1。
  3. SetupSelinux() 完成 SELinux 策略加载后,再次 execv() 进入 /system/bin/init second_stage
  4. SecondStageMain() 才正式进入 Android init 的服务管理、属性服务、rc 解析与服务启动阶段。

3.2 FirstStageMain:第一阶段 init

典型职责:

  • 清理环境变量并设置默认 PATH
  • 挂载 /dev/proc/sys 等基础运行时目录;
  • 创建 /dev/socket/dev/pts 等目录;
  • 读取 kernel cmdline / bootconfig;
  • 执行 first stage mount,尽早挂载系统分区;
  • 通过 execv() 进入 SELinux setup 阶段。

关键跳转逻辑示意:

cpp 复制代码
const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
execv(path, const_cast<char**>(args));

3.3 SetupSelinux:SELinux 策略阶段

该阶段主要完成:

  • 加载 SELinux policy;
  • 设置 SELinux enforcing / permissive;
  • 恢复关键文件安全上下文;
  • 再次 execv() 进入 second_stage

3.4 SecondStageMain:第二阶段 init

SecondStageMain() 是服务管理核心阶段,主要职责包括:

  • 初始化日志、属性系统与 property service;
  • 设置 SIGCHLD 信号处理,避免子进程僵尸化;
  • 创建 ActionManagerServiceList
  • 加载并解析启动脚本;
  • 将 boot action 排入队列;
  • 在事件循环中执行 action、启动 service、响应属性变化。

简化后的逻辑是:

text 复制代码
SecondStageMain
  ├─ PropertyInit / StartPropertyService
  ├─ InstallSignalFdHandler
  ├─ LoadBootScripts
  ├─ QueueBuiltinAction / QueueEventTrigger
  └─ while true:
       ├─ ExecuteOneCommand
       ├─ RestartProcesses
       └─ epoll_wait

4. init.rc 如何导入 Zygote 配置

system/core/rootdir/init.rc 中并不固定写死某一个 Zygote 配置,而是通过系统属性 ro.zygote 动态导入:

rc 复制代码
import /init.${ro.zygote}.rc

常见取值:

ro.zygote 导入文件 含义
zygote32 init.zygote32.rc 仅 32 位 Zygote
zygote64 init.zygote64.rc 仅 64 位 Zygote
zygote32_64 init.zygote32_64.rc 主 32 位 + secondary 64 位
zygote64_32 init.zygote64_32.rc 主 64 位 + secondary 32 位

以 64 位主 Zygote 为例,核心服务配置通常类似:

rc 复制代码
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    onrestart write /sys/power/wake_lock zygote_kwl
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart --only-if-running media.tuner
    onrestart restart netd
    onrestart restart wificond
    task_profiles ProcessCapacityHigh MaxPerformance
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

关键点:

  • service zygote:声明 init service 名称为 zygote
  • /system/bin/app_process64:Zygote 进程的 native 入口程序;
  • -Xzygote:传给 ART/Runtime 的 VM 参数;
  • /system/bin:app_process 参数中的 parent dir;
  • --zygote:声明以 Zygote 模式进入;
  • --start-system-server:主 Zygote 启动后 fork system_server
  • --socket-name=zygote:指定 socket 名称;
  • socket zygote stream 660 root system:由 init 为服务创建 Unix domain socket,供后续 framework 请求 fork app;
  • socket usap_pool_primary:USAP pool 使用的 socket,用于应用启动加速;
  • critical:Zygote 被视为关键服务,异常退出会触发关键进程处理逻辑。

5. init 如何真正启动 Zygote service

init.rc 中常见的 boot action 会触发 class 启动,例如:

rc 复制代码
on nonencrypted
    class_start main
    class_start late_start

on property:vold.decrypt=trigger_restart_framework
    class_start main
    class_start late_start

由于 zygote service 属于 class main,当 class_start main 被执行时,init 会遍历该 class 下的 service,并通过 fork/exec 启动 /system/bin/app_process64

简化流程:

text 复制代码
Parser 解析 init.zygote64.rc
  └─ 生成 Service 对象:name=zygote, exec=/system/bin/app_process64, args=[...]
class_start main
  └─ Service::Start()
      ├─ 创建 socket 等资源
      ├─ fork 子进程
      └─ 子进程 execve("/system/bin/app_process64", argv, env)

6. Native 层:app_process / app_main.cpp

Zygote service 启动后首先进入:

text 复制代码
frameworks/base/cmds/app_process/app_main.cpp

app_main.cpp 负责解析命令参数,并决定进入 Zygote、application 或普通 Java main 模式。

核心逻辑摘要:

cpp 复制代码
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;

while (i < argc) {
    const char* arg = argv[i++];
    if (strcmp(arg, "--zygote") == 0) {
        zygote = true;
        niceName = ZYGOTE_NICE_NAME;
    } else if (strcmp(arg, "--start-system-server") == 0) {
        startSystemServer = true;
    } else if (strcmp(arg, "--application") == 0) {
        application = true;
    } else if (strncmp(arg, "--nice-name=", 12) == 0) {
        niceName.setTo(arg + 12);
    } else if (strncmp(arg, "--", 2) != 0) {
        className.setTo(arg);
        break;
    } else {
        --i;
        break;
    }
}

if (zygote) {
    runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (!className.isEmpty()) {
    runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}

7. AndroidRuntime:从 Native 进入 Java

AndroidRuntime::start() 是 Native 到 Java 的桥梁。它做三件非常关键的事:

  1. 初始化 JNI invocation;
  2. 创建并启动 ART VM;
  3. 查找 Java 入口类和 main(String[] args),通过 JNI 调用。

简化逻辑:

cpp 复制代码
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) {
    JniInvocation jni_invocation;
    jni_invocation.Init(nullptr);

    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }

    if (startReg(env) < 0) {
        return;
    }

    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
}

对于 Zygote 来说,className 是:

text 复制代码
com.android.internal.os.ZygoteInit

最终进入:

java 复制代码
public static void main(String[] argv)

8. Java 层:ZygoteInit.main()

ZygoteInit 是 Java 层 Zygote 初始化的核心类。

核心职责:

  1. 解析 app_process 传入的参数;
  2. 创建 ZygoteServer
  3. 注册 Zygote socket;
  4. 执行 preload;
  5. 启动 system_server
  6. 进入 select/poll 循环等待 fork 请求。

简化主流程:

java 复制代码
public static void main(String[] argv) {
    ZygoteServer zygoteServer = null;

    Runnable caller;
    try {
        Zygote.initNativeState(isPrimaryZygote);
        ZygoteHooks.startZygoteNoThreadCreation();

        zygoteServer = new ZygoteServer(isPrimaryZygote);

        if (!enableLazyPreload) {
            preload(zygoteServer);
        }

        ZygoteHooks.stopZygoteNoThreadCreation();

        if (startSystemServer) {
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
            if (r != null) {
                r.run();
                return;
            }
        }

        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }

    if (caller != null) {
        caller.run();
    }
}

8.1 preload:预加载优化

Zygote 的性能关键在于"先加载,后 fork"。预加载内容包括:

  • preloadClasses():预加载 framework 常用 Java 类;
  • preloadResources():预加载系统资源;
  • preloadSharedLibraries():加载常用 native library;
  • preloadTextResources()preloadOpenGL() 等平台相关资源;
  • 触发 GC,尽可能在 fork 前整理内存。

为什么有效:

  • Zygote 预加载后的内存页在 fork 后被子进程共享;
  • Linux Copy-On-Write 机制保证只有写入时才复制物理页;
  • 大量 app 共享 framework 类和资源,显著降低冷启动成本与总体内存占用。

9. Zygote.forkSystemServer()

system_server 是 Android Java 系统服务的大本营,Zygote 初始化后会首先 fork 它。

简化调用链:

text 复制代码
ZygoteInit.main
  └─ forkSystemServer(...)
      ├─ 构造 uid/gid/capabilities/runtime flags
      ├─ Zygote.forkSystemServer(...)
      │   └─ nativeForkSystemServer(...)
      └─ 子进程 handleSystemServerProcess(...)
          └─ RuntimeInit.zygoteInit(...)
              └─ MethodAndArgsCaller / Runnable
                  └─ com.android.server.SystemServer.main()

典型参数包含:

  • UID/GID:AID_SYSTEM
  • 进程名:system_server
  • Java class:com.android.server.SystemServer
  • capabilities:平台根据配置授予 system_server 所需能力;
  • runtime flags:debuggable、profile、hidden API policy 等。

9.1 父子进程分化

fork 后返回值语义:

text 复制代码
pid == 0:当前处于 system_server 子进程
pid > 0:当前仍为 zygote 父进程
pid < 0:fork 失败

子进程会:

  • 关闭从 Zygote 继承但不应继续持有的 server socket;
  • 设置进程名、runtime 环境;
  • 进入 SystemServer.main()

父进程会:

  • 继续作为 Zygote 存活;
  • 进入 ZygoteServer.runSelectLoop()

10. SystemServer.main()

SystemServer 是 Android framework 层核心服务的启动入口。典型启动流程:

text 复制代码
SystemServer.main
  └─ new SystemServer().run()
      ├─ Looper.prepareMainLooper()
      ├─ System.loadLibrary("android_servers")
      ├─ createSystemContext()
      ├─ startBootstrapServices()
      ├─ startCoreServices()
      ├─ startOtherServices()
      └─ Looper.loop()

服务分层:

  • Bootstrap services:ActivityManagerService、PowerManagerService、PackageManagerService 等启动依赖极强的服务;
  • Core services:BatteryService、UsageStatsService 等核心服务;
  • Other services:WindowManagerService、InputManagerService、ConnectivityService、MediaRouterService 等大量系统能力。

当 ActivityManagerService 准备启动应用进程时,会走到 ProcessList / Process,最后通过 Zygote socket 向 Zygote 发送 fork 请求。


11. ZygoteServer.runSelectLoop()

主 Zygote 进入循环后,主要监听:

  • Zygote server socket;
  • USAP pool socket;
  • 已连接客户端 socket;
  • 辅助 Zygote 或其他 FD。

简化逻辑:

java 复制代码
Runnable runSelectLoop(String abiList) {
    while (true) {
        StructPollfd[] pollFds = ...;
        Os.poll(pollFds, -1);

        for (int pollIndex = pollFds.length - 1; pollIndex >= 0; --pollIndex) {
            if (pollIndex == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
            } else {
                ZygoteConnection connection = peers.get(pollIndex);
                Runnable command = connection.processCommand(this, multipleForksOK);
                if (command != null) {
                    return command;
                }
            }
        }
    }
}

processCommand() 会解析来自 framework 的参数,例如:

text 复制代码
--runtime-args
--setuid=10000
--setgid=10000
--target-sdk-version=35
--nice-name=com.example.app
--seinfo=default
--instruction-set=arm64
--app-data-dir=/data/user/0/com.example.app
android.app.ActivityThread

最终调用 Zygote.forkAndSpecialize() fork app 进程。


12. 应用进程 fork 后如何进入 ActivityThread

应用进程从 Zygote fork 出来后,子进程会进入 RuntimeInit / ZygoteInit.zygoteInit() 路径,初始化 runtime 后反射调用目标 main class。

典型 app 入口:

text 复制代码
android.app.ActivityThread.main(String[] args)

简化链路:

text 复制代码
AMS / ProcessList
  └─ startProcessLocked
      └─ Process.start
          └─ ZygoteProcess.startViaZygote
              └─ 通过 zygote socket 发送参数
ZygoteServer
  └─ ZygoteConnection.processCommand
      └─ Zygote.forkAndSpecialize
          ├─ 父进程:返回 pid 给 system_server
          └─ 子进程:RuntimeInit.zygoteInit
              └─ ActivityThread.main

13. 关键类职责表

类 / 文件 层级 职责
system/core/init/main.cpp Native / init init 入口,按参数分派 first stage、SELinux、second stage
first_stage_init.cpp Native / init 基础挂载、first stage mount、跳转 SELinux setup
selinux.cpp Native / init 加载 SELinux 策略并进入 second stage
init.cpp Native / init second stage 主逻辑,属性服务、rc 解析、service 管理
init.rc init language 导入 init 脚本,触发 boot action,包含 import /init.${ro.zygote}.rc
init.zygote64.rc init language 定义 zygote service、socket、onrestart、critical 等
app_main.cpp Native / framework app_process 入口,解析 --zygote 并调用 AndroidRuntime
AndroidRuntime.cpp Native / framework 创建 ART VM、注册 JNI、调用 Java main
ZygoteInit.java Java / framework Zygote Java 入口,preload、fork system_server、进入 select loop
Zygote.java Java / framework 封装 forkSystemServer、forkAndSpecialize 等 native fork 能力
ZygoteServer.java Java / framework 管理 server socket、USAP socket、select/poll 循环
ZygoteConnection.java Java / framework 解析 socket 命令并触发 fork
RuntimeInit.java Java / framework 子进程 runtime 初始化,最终调用目标 Java main
SystemServer.java Java / services 启动 Android framework 系统服务

14. 与 Android 15 相关的注意点

  1. Android 15 仍沿用 Zygote 作为 Java app 与 system_server 的 fork 源头。
  2. ro.zygote 仍决定 32/64 位 Zygote 拓扑。
  3. 主 Zygote 一般负责启动 system_server,secondary Zygote 不携带 --start-system-server
  4. usap_pool_primary 用于 USAP 机制,优化应用进程创建延迟。
  5. Zygote 是关键进程,被 init 标记为 critical;其异常退出通常意味着 framework 层需要重启甚至触发系统级恢复动作。

15. 代码校验说明

本文件中的代码片段分为两类:

  1. 源码摘要片段:用于说明关键路径,不保证是完整可单独编译文件;但函数名、类名、参数名和调用链基于 AOSP Android 15 r17 对应源码组织。
  2. 命令与 rc 片段:用于说明启动配置和本地校验方式;可按本地网络环境调整 mirror。

本次生成时执行了自动校验:

  • Markdown 代码围栏闭合校验;
  • 关键文件路径出现校验;
  • 关键类名出现校验;
  • 关键调用链节点出现校验;
  • shell 代码块基础语法检查;
  • rc 片段中 service zygotesocket zygoteclass main 等关键字段检查。

校验结果见文末"自动校验结果"。


16. 推荐本地源码核对命令

在已同步 AOSP 后,可使用以下命令核对本文关键点:

bash 复制代码
# init 入口与分阶段逻辑
grep -R "int main(int argc, char\*\* argv)" -n system/core/init/main.cpp
grep -R "FirstStageMain" -n system/core/init
grep -R "SetupSelinux" -n system/core/init
grep -R "SecondStageMain" -n system/core/init

# zygote rc 导入与服务定义
grep -R "init.\${ro.zygote}.rc" -n system/core/rootdir/init.rc
grep -R "service zygote" -n system/core/rootdir/init.zygote*.rc
grep -R "--start-system-server" -n system/core/rootdir/init.zygote*.rc

# app_process 到 ZygoteInit
grep -R "ZygoteInit" -n frameworks/base/cmds/app_process/app_main.cpp
grep -R "AndroidRuntime::start" -n frameworks/base/core/jni/AndroidRuntime.cpp

# Zygote Java 层
grep -R "public static void main" -n frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
grep -R "forkSystemServer" -n frameworks/base/core/java/com/android/internal/os
grep -R "runSelectLoop" -n frameworks/base/core/java/com/android/internal/os

# SystemServer
grep -R "class SystemServer" -n frameworks/base/services/java/com/android/server/SystemServer.java
grep -R "startBootstrapServices" -n frameworks/base/services/java/com/android/server/SystemServer.java

17. 源码链接

  • AOSP manifest tag:https://android.googlesource.com/platform/manifest/+/refs/tags/android-15.0.0_r17
  • system/corehttps://android.googlesource.com/platform/system/core/+/refs/tags/android-15.0.0_r17/
  • frameworks/basehttps://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/
  • init.rchttps://android.googlesource.com/platform/system/core/+/refs/tags/android-15.0.0_r17/rootdir/init.rc
  • init.zygote64.rchttps://android.googlesource.com/platform/system/core/+/refs/tags/android-15.0.0_r17/rootdir/init.zygote64.rc
  • app_main.cpphttps://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/cmds/app_process/app_main.cpp
  • AndroidRuntime.cpphttps://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/core/jni/AndroidRuntime.cpp
  • ZygoteInit.javahttps://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/core/java/com/android/internal/os/ZygoteInit.java
  • Zygote.javahttps://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/core/java/com/android/internal/os/Zygote.java
  • ZygoteServer.javahttps://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/core/java/com/android/internal/os/ZygoteServer.java
  • SystemServer.javahttps://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/services/java/com/android/server/SystemServer.java

18. 自动校验结果

此部分由生成脚本写入。

校验时间 :2026-07-01 07:04:46

总体结果:通过

代码块统计

json 复制代码
{
  "bash": 3,
  "text": 11,
  "cpp": 4,
  "rc": 3,
  "java": 3
}

错误

警告

说明:C++/Java 片段用于流程说明,属于源码摘要,不作为独立翻译单元编译;已对关键调用、关键路径、代码围栏和 rc/shell 片段做自动一致性校验。

---------------------------------------End Line-------------------------------------