Android系统启动--Zygote启动system_server进程的过程--Android 12

上一篇博文介绍了SystemServer启动各种SystemService的过程,本章介绍Zygote孵化SystemServer进程的过程,system_server是进程名称,代码实现在 /frameworks/base/services/java/com/android/server/SystemServer.java。


目录

一、ZygoteInit

二、SystemServer进程启动过程

三、具体函数介绍

1.ZygoteInit.main()

2. ZygoteInit.forkSystemServer()    

3. Zygote.forkSystemServer()    

4. ZygoteInit.handleSystemServerProcess()    

 4. ZygoteInit.zygoteInit()    

5. RuntimeInit.appliactionInit()

6. RuntimeInit.findStaticMain()

7. MethodAndArgsCaller.run()


一、ZygoteInit

路径:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,它是Zygote进程的启动类,作用是预初始化一些类,然后等待UNIX domain socket的指令。基于这些指令fork出继承VM初始状态的子进程。


二、SystemServer进程启动过程

Zygote启动system_server进程基本都在framework Java层,本文基于Android 12,整体过程如下图。

  • ZygoteInit的main()中调用forkSystemServer(),组装启动systemServer进程的参数,调用Zygote.forSystemServer();
  • Zygote.forSystemServer()中调用JNI方法nativeForkSystemServer(),返回pid。
  • pid=0表示运行在子进程中,接着调用handleSystemServerProcess(),在该方法中调用zygoteInit()。
  • zygoteInit()中先通过JNI调用nativeZygoteInit(),最后调用返回RuntimeInit.applicationInit()。
  • applicationInit()中调用自己的findStaticMain(),在后者方法中通过反射获取SystemServer的Class和main(),最后返回MethodAndArgsCaller对象(它implements Runnable)。
  • 最后main()方法调用forSystemServer()返回的MethodAndArgsCaller对象的run(),在其run()调用了SystemServer.main()。

三、具体函数介绍

1.ZygoteInit.main()

main()主要工作:

  • 初始化DDMS(Dalvik Debug Monitor Service);
  • 预加载类、库、各种资源等
  • 创建server端Socket;
  • 调用forSystemServer()开始fork system_server进程,调用其返回的Runnable对象的run(),即通过反射调用SystemServer.main();
  • 调用zygoteServer.runSelectLoop()监听Socket。
public class ZygoteInit {
    public static void main(String[] argv) {
    ZygoteServer zygoteServer = null;
    Runnable caller;
    ...
    RuntimeInit.preForkInit(); //enable DDMS
    ...
    preload(bootTimingsTraceLog); //预加载类、库、资源
    ...
    zygoteServer = new ZygoteServer(isPrimaryZygote); //创建服务器端Socket
    if (startSystemServer) {
        //fork systemServer进程的入口,返回的是MethodAndArgsCaller
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
        // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
        // child (system_server) process.
        if (r != null) {
            //MethodAndArgsCaller类的run()通过反射进去SystemServer.main()
            r.run(); 
            return;
        }
    }
    // The select loop returns early in the child process after a fork and loops forever in the zygote.
    caller = zygoteServer.runSelectLoop(abiList);
    ...
    if (caller != null) {
        caller.run();
    }
}

2. ZygoteInit.forkSystemServer()    

主要工作:

  • 把fork system_server进程的参数String[] args转化为ZygoteArguments类;
  • ZygoteArguments的部分成员变量作为参数来调用Zygote.forSystemServer(),返回fork的子进程的pid;
  • pid=0,表示当前代码运行在子进程system_server中,子进程复制了Zygote进程的地址空间,包括zygote创建的socket,而该socket对system_server进程是没有作用的,因此需要调用zygoteServer.closeServerSocket()关闭。最后调用handleSystemServerProcess()。
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {
    String[] args = {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                        + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs;
    int pid;
    ...
    ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
    try {
        parsedArgs = ZygoteArguments.getInstance(commandBuffer);
    } catch (EOFException e) {
        throw new AssertionError("Unexpected argument error for forking system server", e);
    }

    pid = Zygote.forkSystemServer(
              parsedArgs.mUid, parsedArgs.mGid,
              parsedArgs.mGids,
              parsedArgs.mRuntimeFlags,
              null,
              parsedArgs.mPermittedCapabilities,
              parsedArgs.mEffectiveCapabilities);

    if (pid == 0) {
        //pid=0,表示当前代码运行在子进程system_server中
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
        //system_server进程负责了zygote进程的地址空间,但是它不需要该socket,所以要关闭
        zygoteServer.closeServerSocket();
        return handleSystemServerProcess(parsedArgs);
    }

    return null; 
}

3. Zygote.forkSystemServer()    

该方法主要调用nativeForkSystemServer(),该方法通过JNI调用/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp中该方法。

4. ZygoteInit.handleSystemServerProcess()    

/**
 * Finish remaining work for the newly forked system server process.
 */
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    ...
    ClassLoader cl = getOrCreateSystemServerClassLoader();
    ...
    return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mDisabledCompatChanges, parsedArgs.mRemainingArgs, cl);
}

上述获取ClassLoader c1最终调用该方法,使用boot class loader来加载SystemServer类。

static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
    String libraryPath = System.getProperty("java.library.path");

    // We use the boot class loader, that's what the runtime expects at AOT.
    ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();

    return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
                parent, targetSdkVersion, true /* isNamespaceShared */, null /*     classLoaderName */);
    }

 4. ZygoteInit.zygoteInit()    

public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
                                  String[] argv, ClassLoader classLoader) {

    RuntimeInit.redirectLogStreams(); //重定向log输出
    RuntimeInit.commonInit(); //初始化Runitme
    ZygoteInit.nativeZygoteInit(); //JNI方法,启动Binder线程池
    return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv, classLoader);
}

5. RuntimeInit.appliactionInit()

protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
                                          String[] argv, ClassLoader classLoader) {
    //初始化VM环境
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
    VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
    final Arguments args = new Arguments(argv);
    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader); 
}

6. RuntimeInit.findStaticMain()

该方法就是利用classLoader加载SystemServer类,然后获取其main(),最后返回MethodAndArgsCaller对象。

protected static Runnable findStaticMain(String className, String[] argv,
                                         ClassLoader classLoader) {
    Class<?> cl;
    cl = Class.forName(className, true, classLoader);

    Method m;
    m = cl.getMethod("main", new Class[] { String[].class });
    ...
    return new MethodAndArgsCaller(m, argv);
}

7. MethodAndArgsCaller.run()

static class MethodAndArgsCaller implements Runnable {
    private final Method mMethod;
    private final String[] mArgs;

    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }

    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
           ...
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值