SystemServer 进程启动分析一

326 阅读3分钟

Android 系统中 SystemServer 进程的启动流程,解析其从 Zygote 进程中孵化的核心机制:

一、SystemServer 的核心地位:系统服务的「宿主」

SystemServer 是 Android 系统 Java 层的核心进程,几乎所有系统服务(如 ActivityManagerService、WindowManagerService)都运行在该进程中。其启动分为两个阶段:

  1. 第一阶段:由 Zygote 进程通过 fork 系统调用创建 SystemServer 子进程。
  2. 第二阶段:执行 SystemServer.main() 初始化并启动各类系统服务(后续分析重点)。
    本文聚焦第一阶段:从 Zygote 孵化 SystemServer 进程的关键步骤

二、启动触发:Zygote 的「特殊参数」

1. init.rc 中的配置

在 system/core/rootdir/init.rc 中,Zygote 服务定义包含 --start-system-server 参数:

ini

service zygote /system/bin/app_process64 ... --start-system-server ...
  • 作用:告知 Zygote 在启动后需创建 SystemServer 进程。

2. 参数解析(C++ 层)

Zygote 的启动程序 app_process 解析参数:

c++

while (i < argc) {
    if (strcmp(arg, "--start-system-server") == 0) {
        startSystemServer = true; // 标记为需启动 SystemServer
    }
}
  • 该标记最终传递至 Java 层的 ZygoteInit.main() 方法。

三、Java 层孵化:forkSystemServer 函数

1. 核心逻辑触发

在 ZygoteInit.main() 中,若 startSystemServer 为 true,调用 forkSystemServer()

java

Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
    r.run(); // 子进程执行 SystemServer 逻辑
    return;
}

2. 启动参数准备

为 SystemServer 构造专属启动参数(部分示例):

java

String args[] = {
    "--setuid=1000",        // UID 设置为系统用户(system)
    "--setgid=1000",        // GID 同上
    "--nice-name=system_server", // 进程名
    "com.android.server.SystemServer", // 入口类
};
  • 权限与标识:通过 UID/GID 隔离系统进程,确保其拥有访问系统资源的权限。

3. 调用 native 层 fork 方法

java

pid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid, ...);
  • 该方法通过 JNI 调用 C++ 层的 nativeForkSystemServer 实现进程创建。

四、C++ 层实现:fork 与子进程初始化

1. fork 系统调用

通过 fork() 复制 Zygote 进程,生成父进程(Zygote)和子进程(SystemServer):

c++

pid_t pid = fork();
if (pid == 0) { // 子进程(SystemServer)
    SpecializeCommon(...); // 初始化配置
} else { // 父进程(Zygote)
    waitpid(pid, &status, WNOHANG); // 监控子进程启动状态
}

2. 子进程初始化(SpecializeCommon)

  • 权限设置

    c++

    setresgid(gid, gid, gid); // 设置 GID
    selinux_android_setcon("u:r:system_server:s0"); // SELinux 上下文
    
  • 进程名称与优先级

    c++

    SetThreadName("system_server"); // 设置线程名
    setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT); // 设置优先级
    
  • Binder 初始化
    调用 app_process 的 onZygoteInit() 初始化 Binder 线程池,为跨进程通信(IPC)做准备。

五、控制流转交 Java 层:执行 SystemServer.main ()

1. 反射调用入口函数

子进程通过 handleSystemServerProcess 函数触发 Java 层逻辑:

java

return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mRemainingArgs, cl);
  • 关键步骤

    1. 通用初始化:设置时区、日志系统、网络流量统计等。

    2. Binder 环境初始化:通过 nativeZygoteInit() 调用 C++ 层代码初始化 Binder。

    3. 反射调用 main 方法

      java

      Class<?> cl = Class.forName("com.android.server.SystemServer");
      Method m = cl.getMethod("main", String[].class);
      m.invoke(null, args); // 执行 SystemServer.main(String[] args)
      

2. 进程身份切换完成

至此,子进程完全接管控制权,以 system_server 身份运行,后续将启动各类系统服务(如 AMS、WMS 等)。

六、关键知识点总结

  1. Zygote 的「双重角色」

    • 既是应用进程的孵化器,也是 SystemServer 的「母体」,通过 fork 高效复用资源。
  2. 权限与隔离

    • SystemServer 以 UID 1000(system 用户)运行,通过 SELinux 限制其访问权限,确保系统安全。
  3. 跨层协作

    • C++ 层负责进程创建和底层配置,Java 层通过反射启动高层逻辑,体现 Android 系统的分层架构设计。
  4. 监控与健壮性

    • Zygote 父进程通过 waitpid 监控 SystemServer 启动状态,若失败则重启 Zygote,确保系统稳定性。

七、类比说明

SystemServer 的启动如同「组建政府机构」:

  • Zygote 是「行政中心」:负责创建机构(进程),并提供基础办公设施(预加载资源、Binder 环境)。

  • fork 是「机构复制」:快速创建专门机构(SystemServer),继承行政中心的资源,但拥有独立权限(UID/GID)。

  • SystemServer.main () 是「机构运作」:机构正式挂牌后,各部门(系统服务)开始履行职责(如 ActivityManager 管理应用生命周期)。

通过这一流程,Android 系统完成从「孵化环境」到「功能执行」的过渡,为用户态服务提供运行基础。