Android系统启动-SystemServer上篇

AntonyCourt 9年前
   <blockquote>     <p>基于Android 6.0的源码剖析, 分析Android启动过程的system_server进程</p>    </blockquote>    <pre>  <code class="language-java">/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java  /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java  /frameworks/base/core/services/java/com/android/server/SystemServer.java    /frameworks/base/core/java/com/android/internal/os/Zygote.java  /frameworks/base/core/jni/com_android_internal_os_Zygote.cpp    /frameworks/base/cmds/app_process/App_main.cpp (内含AppRuntime类)  /frameworks/base/core/jni/AndroidRuntime.cpp  </code></pre>    <h3>启动流程</h3>    <p>SystemServer的在Android体系中所处的地位,SystemServer由Zygote fork生成的,进程名为<code>system_server</code>,该进程承载着framework的核心服务。<a href="http://www.open-open.com/lib/view/open1456803765078.html">Android系统启动-zygote篇</a>中讲到Zygote启动过程中,会调用startSystemServer(),可知<code>startSystemServer()</code>函数是system_server启动流程的起点,启动流程图如下:</p>    <p><img alt="Android系统启动-SystemServer上篇" src="https://simg.open-open.com/show/1f456bbdadb2f67674923b068deb7150.jpg" width="1147" height="329"></p>    <p>上图前4步骤(即颜色为紫色的流程)运行在是<code>Zygote</code>进程,从第5步(即颜色为蓝色的流程)ZygoteInit.handleSystemServerProcess开始是运行在新创建的<code>system_server</code>,这是fork机制实现的(fork会返回2次)。下面从startSystemServer()开始讲解详细启动流程。</p>    <h3>1. startSystemServer</h3>    <p>[–>ZygoteInit.java]</p>    <pre>  <code class="language-java">private static boolean startSystemServer(String abiList, String socketName)          throws MethodAndArgsCaller, RuntimeException {   ...      //参数准备      String args[] = {          "--setuid=1000",          "--setgid=1000",          "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",          "--capabilities=" + capabilities + "," + capabilities,          "--nice-name=system_server",          "--runtime-args",          "com.android.server.SystemServer",      };        ZygoteConnection.Arguments parsedArgs = null;      int pid;      try {          //用于解析参数,生成目标格式          parsedArgs = new ZygoteConnection.Arguments(args);          ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);          ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);            // fork子进程,该进程是system_server进程【见小节2】          pid = Zygote.forkSystemServer(                  parsedArgs.uid, parsedArgs.gid,                  parsedArgs.gids,                  parsedArgs.debugFlags,                  null,                  parsedArgs.permittedCapabilities,                  parsedArgs.effectiveCapabilities);      } catch (IllegalArgumentException ex) {          throw new RuntimeException(ex);      }        //进入子进程system_server      if (pid == 0) {          if (hasSecondZygote(abiList)) {              waitForSecondaryZygote(socketName);          }          // 完成system_server进程剩余的工作 【见小节5】          handleSystemServerProcess(parsedArgs);      }      return true;  }  </code></pre>    <p>准备参数并fork新进程,从上面可以看出system server进程参数信息为uid=1000,gid=1000,进程名为sytem_server,从zygote进程fork新进程后,需要关闭zygote原有的socket。另外,对于有两个zygote进程情况,需等待第2个zygote创建完成。</p>    <h3>2 forkSystemServer</h3>    <p>[–>Zygote.java]</p>    <pre>  <code class="language-java">public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,          int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {      VM_HOOKS.preFork();      // 调用native方法fork system_server进程【见小节3】      int pid = nativeForkSystemServer(              uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);      if (pid == 0) {          Trace.setTracingEnabled(true);      }      VM_HOOKS.postForkCommon();      return pid;  }  </code></pre>    <p>nativeForkSystemServer(),该native方法事在AndroidRuntime.cpp中注册的,然后调用com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法完成nativeForkSystemServer()与com_android_internal_os_Zygote_nativeForkSystemServer()方法的一一映射关系,也就是会进入下面的方法。</p>    <h3>3. nativeForkSystemServer</h3>    <p>[–>com_android_internal_os_Zygote.cpp]</p>    <pre>  <code class="language-java">static jint com_android_internal_os_Zygote_nativeForkSystemServer(          JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,          jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,          jlong effectiveCapabilities) {    //fork子进程,见【见小节4】    pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,                                        debug_flags, rlimits,                                        permittedCapabilities, effectiveCapabilities,                                        MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,                                        NULL, NULL);    if (pid > 0) {        // zygote进程,检测system_server进程是否创建        gSystemServerPid = pid;        int status;        if (waitpid(pid, &status, WNOHANG) == pid) {            //当system_server进程死亡后,重启zygote进程            RuntimeAbort(env);        }    }    return pid;  }  </code></pre>    <p>当system_server进程创建失败时,将会重启zygote进程。这里需要注意,对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,system_server的父进程,一般来说64位系统其父进程是zygote64进程</p>    <ol>     <li>当kill system_server进程后,只重启zygote64和system_server,不重启zygote;</li>     <li>当kill zygote64进程后,只重启zygote64和system_server,也不重启zygote;</li>     <li>当kill zygote进程,则重启zygote、zygote64以及system_server。</li>    </ol>    <h3>4. ForkAndSpecializeCommon</h3>    <p>[–>com_android_internal_os_Zygote.cpp]</p>    <pre>  <code class="language-java">static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,                                       jint debug_flags, jobjectArray javaRlimits,                                       jlong permittedCapabilities, jlong effectiveCapabilities,                                       jint mount_external,                                       jstring java_se_info, jstring java_se_name,                                       bool is_system_server, jintArray fdsToClose,                                       jstring instructionSet, jstring dataDir) {    SetSigChldHandler(); //设置子进程的signal信号处理函数    pid_t pid = fork(); //fork子进程    if (pid == 0) {      //进入子进程      DetachDescriptors(env, fdsToClose); //关闭并清除文件描述符        if (!is_system_server) {          //对于非system_server子进程,则创建进程组          int rc = createProcessGroup(uid, getpid());      }      SetGids(env, javaGids); //设置设置group      SetRLimits(env, javaRlimits); //设置资源limit        int rc = setresgid(gid, gid, gid);      rc = setresuid(uid, uid, uid);        SetCapabilities(env, permittedCapabilities, effectiveCapabilities);      SetSchedulerPolicy(env); //设置调度策略         //selinux上下文      rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);        if (se_info_c_str == NULL && is_system_server) {        se_name_c_str = "system_server";      }      if (se_info_c_str != NULL) {        SetThreadName(se_name_c_str); //设置线程名为system_server,方便调试      }      UnsetSigChldHandler(); //设置子进程的signal信号处理函数为默认函数      //等价于调用zygote.callPostForkChildHooks()      env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,                                is_system_server ? NULL : instructionSet);      ...      } else if (pid > 0) {      //进入父进程,即zygote进程    }    return pid;  }  </code></pre>    <p>fork()创建新进程,采用copy on write方式,这是linux创建进程的标准方法,会有两次return,对于pid==0为子进程的返回,对于pid>0为父进程的返回。 到此system_server进程已完成了创建的所有工作,接下来开始了system_server进程的真正工作。在前面startSystemServer()方法中,zygote进程执行完forkSystemServer()后,新创建出来的system_server进程便进入handleSystemServerProcess()方法。关于fork(),可查看另一个文章<a href="http://www.open-open.com/lib/view/open1459854633503.html">理解Android进程创建流程</a>。</p>    <h3>5. handleSystemServerProcess</h3>    <p>[–>ZygoteInit.java]</p>    <pre>  <code class="language-java">private static void handleSystemServerProcess(          ZygoteConnection.Arguments parsedArgs)          throws ZygoteInit.MethodAndArgsCaller {        closeServerSocket(); //关闭父进程zygote复制而来的Socket        Os.umask(S_IRWXG | S_IRWXO);        if (parsedArgs.niceName != null) {          Process.setArgV0(parsedArgs.niceName); //设置当前进程名为"system_server"      }        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");      if (systemServerClasspath != null) {          //执行dex优化操作【见小节6】          performSystemServerDexOpt(systemServerClasspath);      }        if (parsedArgs.invokeWith != null) {          String[] args = parsedArgs.remainingArgs;            if (systemServerClasspath != null) {              String[] amendedArgs = new String[args.length + 2];              amendedArgs[0] = "-cp";              amendedArgs[1] = systemServerClasspath;              System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);          }          //启动应用进程          WrapperInit.execApplication(parsedArgs.invokeWith,                  parsedArgs.niceName, parsedArgs.targetSdkVersion,                  VMRuntime.getCurrentInstructionSet(), null, args);      } else {          ClassLoader cl = null;          if (systemServerClasspath != null) {              创建类加载器,并赋予当前线程              cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());              Thread.currentThread().setContextClassLoader(cl);          }            //system_server故进入此分支【见小节7】          RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);      }        /* should never reach here */  }  </code></pre>    <p>此处<code>systemServerClasspath</code>至少包含/system/framework/services.jar,当然也可以不止于此,比如还可以包含/system/framework/ethernet-service.jar, /system/framework/wifi-service.jar等。</p>    <h3>6. performSystemServerDexOpt</h3>    <p>[–>ZygoteInit.java]</p>    <pre>  <code class="language-java">private static void performSystemServerDexOpt(String classPath) {      final String[] classPathElements = classPath.split(":");      //创建一个与installd的建立socket连接      final InstallerConnection installer = new InstallerConnection();      //执行ping操作,直到与installd服务端连通为止      installer.waitForConnection();      final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();        try {          for (String classPathElement : classPathElements) {              final int dexoptNeeded = DexFile.getDexOptNeeded(                      classPathElement, "*", instructionSet, false /* defer */);              if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {                  //以system权限,执行dex文件优化                  installer.dexopt(classPathElement, Process.SYSTEM_UID, false,                          instructionSet, dexoptNeeded);              }          }      } catch (IOException ioe) {          throw new RuntimeException("Error starting system_server", ioe);      } finally {          installer.disconnect(); //断开与installd的socket连接      }  }  </code></pre>    <p>将classPath字符串中的apk,分别进行dex优化操作。真正执行优化工作通过socket通信将相应的命令参数,发送给installd来完成。</p>    <h3>7. zygoteInit</h3>    <p>[–>RuntimeInit.java]</p>    <pre>  <code class="language-java">public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)          throws ZygoteInit.MethodAndArgsCaller {        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");      redirectLogStreams(); //重定向log输出        commonInit(); // 通用的一些初始化【见小节8】      nativeZygoteInit(); // zygote初始化 【见小节9】      applicationInit(targetSdkVersion, argv, classLoader); // 应用初始化【见小节10】  }  </code></pre>    <h3>8. commonInit</h3>    <p>[–>RuntimeInit.java]</p>    <pre>  <code class="language-java">private static final void commonInit() {      // 设置默认的未捕捉异常处理方法      Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());        // 设置市区,中国时区为"Asia/Shanghai"      TimezoneGetter.setInstance(new TimezoneGetter() {          @Override          public String getId() {              return SystemProperties.get("persist.sys.timezone");          }      });      TimeZone.setDefault(null);        //重置log配置      LogManager.getLogManager().reset();       new AndroidConfig();         // 设置默认的HTTP User-agent格式,用于 HttpURLConnection。      String userAgent = getDefaultUserAgent();      System.setProperty("http.agent", userAgent);        // 设置socket的tag,用于网络流量统计      NetworkManagementSocketTagger.install();  }  </code></pre>    <p>默认的HTTP User-agent格式,例如:</p>    <pre>  <code class="language-java"> "Dalvik/1.1.0 (Linux; U; Android 6.0.1;LenovoX3c70 Build/LMY47V)".  </code></pre>    <h3>9. nativeZygoteInit</h3>    <p>nativeZygoteInit()方法在AndroidRuntime.cpp中,进行了jni映射,对应下面的方法。</p>    <p>[–>AndroidRuntime.cpp]</p>    <pre>  <code class="language-java">static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)  {      gCurRuntime->onZygoteInit(); //此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的  }  </code></pre>    <p>[–>app_main.cpp]</p>    <pre>  <code class="language-java">virtual void onZygoteInit()  {      sp<ProcessState> proc = ProcessState::self();      proc->startThreadPool(); //启动新binder线程  }  </code></pre>    <p>ProcessState::self()是单例模式,主要工作是调用open()打开/dev/binder驱动设备,再利用mmap()映射内核的地址空间,将Binder驱动的fd赋值ProcessState对象中的变量mDriverFD,用于交互操作。startThreadPool()是创建一个新的binder线程,不断进行talkWithDriver(),在binder系列文章中的<a href="/misc/goto?guid=4959669985317934411">注册服务(addService)</a>详细这两个方法的执行原理。</p>    <h3>10. applicationInit</h3>    <p>[–>RuntimeInit.java]</p>    <pre>  <code class="language-java">private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)          throws ZygoteInit.MethodAndArgsCaller {      //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用      nativeSetExitWithoutCleanup(true);        //设置虚拟机的内存利用率参数值为0.75      VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);      VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);        final Arguments args;      try {          args = new Arguments(argv); //解析参数      } catch (IllegalArgumentException ex) {          Slog.e(TAG, ex.getMessage());          return;      }        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);        //调用startClass的static方法 main() 【见小节11】      invokeStaticMain(args.startClass, args.startArgs, classLoader);  } 在startSystemServer()方法中通过硬编码初始化参数,可知此处args.startClass为"com.android.server.SystemServer"。  </code></pre>    <h3>11. invokeStaticMain</h3>    <p>[–>RuntimeInit.java]</p>    <pre>  <code class="language-java">private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)          throws ZygoteInit.MethodAndArgsCaller {      Class<?> cl;        try {          cl = Class.forName(className, true, classLoader);      } catch (ClassNotFoundException ex) {          throw new RuntimeException(                  "Missing class when invoking static main " + className, ex);      }        Method m;      try {          m = cl.getMethod("main", new Class[] { String[].class });      } catch (NoSuchMethodException ex) {          throw new RuntimeException( "Missing static main on " + className, ex);      } catch (SecurityException ex) {          throw new RuntimeException(                  "Problem getting static main on " + className, ex);      }        int modifiers = m.getModifiers();      if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {          throw new RuntimeException(                  "Main method is not public and static on " + className);      }        //通过抛出异常,回到ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率。【见小节12】      throw new ZygoteInit.MethodAndArgsCaller(m, argv);  }  </code></pre>    <h3>12. MethodAndArgsCaller</h3>    <p>在<a href="http://www.open-open.com/lib/view/open1456803765078.html">Android系统启动-zygote篇</a>中遗留了一个问题没有讲解,如下:</p>    <p>[–>ZygoteInit.java]</p>    <pre>  <code class="language-java">public static void main(String argv[]) {      try {          startSystemServer(abiList, socketName);//启动system_server          ....      } catch (MethodAndArgsCaller caller) {          caller.run(); //【见小节13】      } catch (RuntimeException ex) {          closeServerSocket();          throw ex;      }  }  </code></pre>    <p>现在已经很明显了,是invokeStaticMain()方法中抛出的异常<code>MethodAndArgsCaller</code>,从而进入caller.run()方法。</p>    <p>[–>ZygoteInit.java]</p>    <pre>  <code class="language-java">public static class MethodAndArgsCaller extends Exception          implements Runnable {        public void run() {          try {              //根据传递过来的参数,可知此处通过反射机制调用的是SystemServer.main()方法              mMethod.invoke(null, new Object[] { mArgs });           } catch (IllegalAccessException ex) {              throw new RuntimeException(ex);          } catch (InvocationTargetException ex) {              Throwable cause = ex.getCause();              if (cause instanceof RuntimeException) {                  throw (RuntimeException) cause;              } else if (cause instanceof Error) {                  throw (Error) cause;              }              throw new RuntimeException(ex);          }      }  }  </code></pre>    <p>到此,总算是进入到了SystemServer类的main()方法, 在文章<a href="http://www.open-open.com/lib/view/open1463014879470.html">Android系统启动-SystemServer下篇</a>中会紧接着这里开始讲述。</p>    <p>来源:<a href="/misc/goto?guid=4959673005241344691">http://gityuan.com/2016/02/14/android-system-server/</a></p>