Android 15 r17 Init 与 Zygote 启动流程整理
目标:基于 AOSP Android 15
android-15.0.0_r17,梳理从 Linux Kernel 拉起init,到init解析.rc并启动zygote,再到 Zygote 进入 Java 层、预加载、forksystem_server、监听应用孵化请求的主干流程。重点涉及类:
ZygoteInit、Zygote、ZygoteServer、ZygoteConnection、RuntimeInit、AndroidRuntime、SystemServer,以及init相关 Native 代码和.rc配置。
1. 参考源码范围
本文按以下 AOSP tag 组织:
- Android 15 r17:
android-15.0.0_r17 system/core/init/main.cppsystem/core/init/first_stage_init.cppsystem/core/init/selinux.cppsystem/core/init/init.cppsystem/core/rootdir/init.rcsystem/core/rootdir/init.zygote*.rcframeworks/base/cmds/app_process/app_main.cppframeworks/base/core/jni/AndroidRuntime.cppframeworks/base/core/java/com/android/internal/os/ZygoteInit.javaframeworks/base/core/java/com/android/internal/os/Zygote.javaframeworks/base/core/java/com/android/internal/os/ZygoteServer.javaframeworks/base/core/java/com/android/internal/os/ZygoteConnection.javaframeworks/base/core/java/com/android/internal/os/RuntimeInit.javaframeworks/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);
}
主流程可以理解为:
- Kernel 首次执行
/init,无second_stage参数,进入FirstStageMain()。 - 第一阶段完成必要挂载后,通过
execv()重新执行/system/bin/init selinux_setup,仍保持 PID 1。 SetupSelinux()完成 SELinux 策略加载后,再次execv()进入/system/bin/init second_stage。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 信号处理,避免子进程僵尸化;
- 创建
ActionManager、ServiceList; - 加载并解析启动脚本;
- 将 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 启动后 forksystem_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 的桥梁。它做三件非常关键的事:
- 初始化 JNI invocation;
- 创建并启动 ART VM;
- 查找 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 初始化的核心类。
核心职责:
- 解析
app_process传入的参数; - 创建
ZygoteServer; - 注册 Zygote socket;
- 执行 preload;
- 启动
system_server; - 进入 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 相关的注意点
- Android 15 仍沿用 Zygote 作为 Java app 与
system_server的 fork 源头。 ro.zygote仍决定 32/64 位 Zygote 拓扑。- 主 Zygote 一般负责启动
system_server,secondary Zygote 不携带--start-system-server。 usap_pool_primary用于 USAP 机制,优化应用进程创建延迟。- Zygote 是关键进程,被 init 标记为
critical;其异常退出通常意味着 framework 层需要重启甚至触发系统级恢复动作。
15. 代码校验说明
本文件中的代码片段分为两类:
- 源码摘要片段:用于说明关键路径,不保证是完整可单独编译文件;但函数名、类名、参数名和调用链基于 AOSP Android 15 r17 对应源码组织。
- 命令与 rc 片段:用于说明启动配置和本地校验方式;可按本地网络环境调整 mirror。
本次生成时执行了自动校验:
- Markdown 代码围栏闭合校验;
- 关键文件路径出现校验;
- 关键类名出现校验;
- 关键调用链节点出现校验;
- shell 代码块基础语法检查;
- rc 片段中
service zygote、socket zygote、class 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/core:https://android.googlesource.com/platform/system/core/+/refs/tags/android-15.0.0_r17/frameworks/base:https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/init.rc:https://android.googlesource.com/platform/system/core/+/refs/tags/android-15.0.0_r17/rootdir/init.rcinit.zygote64.rc:https://android.googlesource.com/platform/system/core/+/refs/tags/android-15.0.0_r17/rootdir/init.zygote64.rcapp_main.cpp:https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/cmds/app_process/app_main.cppAndroidRuntime.cpp:https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/core/jni/AndroidRuntime.cppZygoteInit.java:https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/core/java/com/android/internal/os/ZygoteInit.javaZygote.java:https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/core/java/com/android/internal/os/Zygote.javaZygoteServer.java:https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-15.0.0_r17/core/java/com/android/internal/os/ZygoteServer.javaSystemServer.java:https://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-------------------------------------