筆記:Zygote和SystemServer進程啓動過程

簡述

Android設備啓動過程當中,先是Linux內核加載完,接着Android中的第一個進程init啓動,它會啓動一些須要開機啓動的進程。
Zygote就是進程init啓動起來的。Android中全部應用程序進程,以及運行系統關鍵服務的System進程都是由Zygote建立的。它經過複製自身的形式建立其它進程。Zygote在啓動時會在內部建立一個虛擬機實例,所以,經過複製Zygote獲得的其它應用程序進程和System進程均可以快速地在內部得到一個虛擬機地拷貝。Zygote啓動完成後就當即將System進程啓動,以便各類關鍵服務被啓動運行。java

Zygote的啓動

它以服務的形式被啓動。android

建立虛擬機

進程內建立一個虛擬機實例,並註冊一系列JNI方法。
frameworks/base/core/jni/AndroidRuntime.cppapp

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

接下來執行「com.android.internal.os.ZygoteInit」Java類的main方法繼續執行啓動。socket

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建立新的應用程序進程。ide

建立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進程的啓動。oop

輪詢等待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建立新應用程序進程的請求。ui

System進程的啓動

ZygoteInit.handleSystemServerProcess()執行System進程的啓動操做。.net

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方法。debug

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編寫)

相關文章
相關標籤/搜索