笔记:Zygote和SystemServer进程启动过程

简述

Android设备启动过程中,先是Linux内核加载完,接着Android中的第一个进程init启动,它会启动一些需要开机启动的进程。
Zygote就是进程init启动起来的。Android中所有应用程序进程,以及运行系统关键服务的System进程都是由Zygote创建的。它通过复制自身的形式创建其它进程。Zygote在启动时会在内部创建一个虚拟机实例,因此,通过复制Zygote得到的其它应用程序进程和System进程都可以快速地在内部获得一个虚拟机地拷贝。Zygote启动完成后就立即将System进程启动,以便各种关键服务被启动运行。

Zygote的启动

它以服务的形式被启动。

创建虚拟机

进程内创建一个虚拟机实例,并注册一系列JNI方法。
frameworks/base/core/jni/AndroidRuntime.cpp

/* start the virtual machine. */
startVM(&mJavaVM, &env);
/* Register android functions. */
startReg(env);

接下来执行“com.android.internal.os.ZygoteInit”Java类的main方法继续执行启动。

ZygoteInit.main

package com.android.internal.os;
import android.net.LocalServerSocket;
...
public class ZygoteInit {
  private static LocalServerSocket sServerSocket;

  public static void main(String argv[]) {
    ...
    registerZygoteSocket();
    ...
    if (argv[1].equals("true")) {
        startSystemServer();
    } else if (!argv[1].equals("false")) {
        throw new RuntimeException(argv[0] + USAGE_STRING);
    }
    ...
    if (ZYGOTE_FORK_MODE) {
        runForkMode();
    } else {
        runSelectLoopMode();
    }
    ...
    closeServerSocket();
    ...
  }
}

创建Socket

Zygote调用registerZygoteSocket();创建一个LocalServerSocket sServerSocket的Server端Socket,等待以后运行在System进程中的服务ActivityManagerService创建的Client端Socket连接,然后通过Socket进程间通信通知Zygote创建新的应用程序进程。

创建System进程

/**
 * Prepare the arguments and fork for the system server process.
 */
private static boolean startSystemServer()
        throws MethodAndArgsCaller, RuntimeException {
    /* Hardcoded command line to start the system server */
    String args[] = new String[] {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
            "--capabilities=130104352,130104352",
            "--rlimit=8,",
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ...
    ZygoteConnection.Arguments parsedArgs = null;
    int pid;

    try {
        parsedArgs = new ZygoteConnection.Arguments(args);

        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids, debugFlags, rlimits,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    if (pid == 0) {
        handleSystemServerProcess(parsedArgs);
    }

    return true;
}

变量args保存启动System进程的参数。
Zygote.forkSystemServer()复制当前进程来创建子进程。
handleSystemServerProcess()继续处理System进程的启动。

轮询等待AMS请求创建App进程

private static void runSelectLoopMode() throws MethodAndArgsCaller {
  ArrayList<FileDescriptor> fds = new ArrayList();
  ArrayList<ZygoteConnection> peers = new ArrayList();
  FileDescriptor[] fdArray = new FileDescriptor[4];

  fds.add(sServerSocket.getFileDescriptor());
  peers.add(null);

  while (true) {
    ...
      try {
          fdArray = fds.toArray(fdArray);
          index = selectReadable(fdArray);
      } catch (IOException ex) {
          throw new RuntimeException("Error in select()", ex);
      }

      if (index < 0) {
          throw new RuntimeException("Error in select()");
      } else if (index == 0) {
          ZygoteConnection newPeer = acceptCommandPeer();
          peers.add(newPeer);
          fds.add(newPeer.getFileDesciptor());
      } else {
          boolean done;
          done = peers.get(index).runOnce();

          if (done) {
              peers.remove(index);
              fds.remove(index);
          }
      }
  }
}

/**
 * Waits for and accepts a single command connection. Throws
 * RuntimeException on failure.
 */
private static ZygoteConnection acceptCommandPeer() {
    try {
        return new ZygoteConnection(sServerSocket.accept());
    } catch (IOException ex) {
        throw new RuntimeException(
                "IOException during accept()", ex);
    }
}

无限循环,等待来自AMS创建的Socket连接。
sServerSocket在fds[0]位置。
每当accept()返回一个连接后,将对应此连接的newPeer.getFileDesciptor()套接字描述添加到fds(第0位置后),下一次读取到数据时,若在fds[0]以后的,说明是前面的newPeer连接收到的AMS的创建新应用程序进程的请求。
runOnce()用来处理AMS创建新应用程序进程的请求。

System进程的启动

ZygoteInit.handleSystemServerProcess()执行System进程的启动操作。

ZygoteInit.handleSystemServerProcess()

private static void handleSystemServerProcess(
      ZygoteConnection.Arguments parsedArgs)
      throws ZygoteInit.MethodAndArgsCaller {

  closeServerSocket();

  /*
   * Pass the remaining arguments to SystemServer.
   * "--nice-name=system_server com.android.server.SystemServer"
   */
  RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
  /* should never reach here */
}

Zygote复制自身创建的子进程做为System进程,这样它得到了Zygote的Server Socket,但是用不到,所以第一句closeServerSocket()关闭此套接字。

RuntimeInit.zygoteInit

package com.android.internal.os;

public class RuntimeInit {
  public static final void zygoteInit(String[] argv)
          throws ZygoteInit.MethodAndArgsCaller {
      ...
      commonInit();
      zygoteInitNative();
      ...
      // Remaining arguments are passed to the start class's static main
      String startClass = argv[curArg++];
      String[] startArgs = new String[argv.length - curArg];

      System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
      invokeStaticMain(startClass, startArgs);
  }  
}

zygoteInitNative()在System进程中启动一个Binder线程池。
RuntimeInit.invokeStaticMain()静态方法调用"com.android.server.SystemServer"的main方法。

SystemServer.main

传递调用native方法init1():

class SystemServer {
  /**
     * This method is called from Zygote to initialize the system. This will cause the native
     * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
     * up into init2() to start the Android services.
     */
    native public static void init1(String[] args);
}

init1()的工作:
注册Service Manager的死亡通知:调用binderDied()。System进程执行kill结束自己。

创建SurfaceFlinger、和SensorService两个服务。

返回SystemServer.init2()继续启动java语言开发的系统服务。

SystemServer.init2

public static final void init2() {
    Thread thr = new ServerThread();
    thr.setName("android.server.ServerThread");
    thr.start();
}

ServerThread继承自Thread。

ServerThread.run

class ServerThread extends Thread {
  @Override
  public void run() {
      Looper.prepare();
      ...
      // Critical services...
      try {
          ...
          Slog.i(TAG, "Activity Manager");
          context = ActivityManagerService.main(factoryTest);
          ...
          Slog.i(TAG, "Package Manager");
          pm = PackageManagerService.main(context,
                  factoryTest != SystemServer.FACTORY_TEST_OFF);
          ...
          Slog.i(TAG, "Content Manager");
          ContentService.main(context,
                  factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
          ...
          Slog.i(TAG, "Window Manager");
          wm = WindowManagerService.main(context, power,
                  factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
          ServiceManager.addService(Context.WINDOW_SERVICE, wm);
          ...
          ((ActivityManagerService)ServiceManager.getService("activity"))
                  .setWindowManager(wm);
          ...
      } catch (RuntimeException e) {
          Slog.e("System", "Failure starting core service", e);
      }
      ...
      Looper.loop();
      Slog.d(TAG, "System ServerThread is exiting!");
  }
}

启动各个Service然后注册到ServiceManager。
各个服务都使用Binder和其它服务使用者进程进行就行交互。

(本文使用Atom编写)

posted @ 2017-01-16 19:40  everhad  阅读(462)  评论(0编辑  收藏  举报