查看原文
其他

Android 10.0系统启动之SystemServer进程(一)-「Android取经之路」

IngresGe IngresGe 2021-11-05

前几节已经讲完了Android10.0的Init启动过程以及Zygote启动流程,这一节主要讲解SystemServer进程。

Android取经之路——启动篇

Android系统架构-[Android取经之路]

Android是怎么启动的-[Android取经之路]

Android系统启动之init进程(一)-「Android取经之路」

Android系统启动之init进程(二)-「Android取经之路」

Android 10.0系统启动之init进程(三)-「Android取经之路」

Android 10.0系统启动之init进程(四)-「Android取经之路」

Android 10.0系统启动之Zygote进程(一)-「Android取经之路」

Android 10.0系统启动之Zygote进程(二)-「Android取经之路」

Android 10.0系统启动之Zygote进程(三)-「Android取经之路」

Android 10.0系统启动之Zygote进程(四)-「Android取经之路」


1. 概述

上一节讲解了Zygote进程的整个启动流程。Zygote是所有应用的鼻祖。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。Zygote fork的第一个进程就是SystemServer,其在手机中的进程名为 system_server。

system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等90多个核心系统服务。这些服务以不同的线程方式存在于system_server这个进程中。

接下来,就让我们透过Android系统源码一起来分析一下system_server的整个启动过程。


2. 核心源码

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java/frameworks/base/core/java/com/android/internal/os/Zygote.java/frameworks/base/services/java/com/android/server/SystemServer.java/frameworks/base/services/core/java/com/android/serverSystemServiceManager.java/frameworks/base/services/core/java/com/android/ServiceThread.java/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java/frameworks/base/core/java/android/app/ActivityThread.java/frameworks/base/core/java/android/app/LoadedApk.java/frameworks/base/core/java/android/app/ContextImpl.java/frameworks/base/core/jni/AndroidRuntime.cpp/frameworks/base/core/jni/com_android_internal_os_ZygoteInit.cpp/frameworks/base/cmds/app_process/app_main.cpp



3. 架构

3.1 架构图

SystemServer 被Zygote进程fork出来后,用来创建ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等80多个核心系统服务

3.2 服务启动

4. 源码分析

4.1 SystemServer fork流程分析

4.1.1 [ZygoteInit.java] main()

说明:Zygote进程,通过fork()函数,最终孵化出system_server的进程,通过反射的方法启动SystemServer.java的main()方法

源码:


public static void main(String argv[]) { ZygoteServer zygoteServer = null; ... try { zygoteServer = new ZygoteServer(isPrimaryZygote); if (startSystemServer) { //fork system_server 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) { r.run(); //启动SystemServer.java的main() return; //Android 8.0之前是通过抛异常的方式来启动,这里是直接return出去,用来清空栈,提高栈帧利用率 } } caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception", ex); throw ex; } finally { if (zygoteServer != null) { zygoteServer.closeServerSocket(); } } if (caller != null) { caller.run(); } ...}



4.1.2 [ZygoteInit.java] forkSystemServer()

说明:准备参数,用来进行system_server的fork,从参数可知,pid=1000,gid=1000,进程名nick-name=system_server

当有两个Zygote进程时,需要等待第二个Zygote创建完成。由于fork时会拷贝socket,因此,在fork出system_server进程后,需要关闭Zygote原有的socket


源码:


private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { ...... //参数准备,uid和gid都是为1000 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", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT, "com.android.server.SystemServer", }; ZygoteArguments parsedArgs = null; int pid; try { //将上面准备的参数,按照ZygoteArguments的风格进行封装 parsedArgs = new ZygoteArguments(args); Zygote.applyDebuggerSystemProperty(parsedArgs); Zygote.applyInvokeWithSystemProperty(parsedArgs); //通过fork"分裂"出子进程system_server /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, null, parsedArgs.mPermittedCapabilities, parsedArgs.mEffectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } //进入子进程system_server if (pid == 0) { // 处理32_64和64_32的情况 if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); //需要等待第二个Zygote创建完成 } // fork时会copy socket,Zygote原有的socket需要关闭 zygoteServer.closeServerSocket(); // system server进程处理自己的工作 return handleSystemServerProcess(parsedArgs); } return null;}


4.1.3 [Zygote.java] forkSystemServer()

说明:这里的nativeForkSystemServer()最终是通过JNI,调用Nativate C空间的com_android_internal_os_Zygote_nativeForkSystemServer()

来fork system_server

源码:


public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { ZygoteHooks.preFork(); // Resets nice priority for zygote process. resetNicePriority(); //调用native的方法来fork system_server //最终调用native的方法:com_android_internal_os_Zygote_nativeForkSystemServer int pid = nativeForkSystemServer( uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities); // Enable tracing as soon as we enter the system_server. if (pid == 0) { Trace.setTracingEnabled(true, runtimeFlags); } ZygoteHooks.postForkCommon(); return pid;}



[com_android_internal_os_Zygote.cpp]

说明:JNI注册的映射关系


static const JNINativeMethod gMethods[] = { { "nativeForkSystemServer", "(II[II[[IJJ)I", (void *) com_android_internal_os_Zygote_nativeForkSystemServer },}



4.1.4 [com_android_internal_os_Zygote.cpp]

com_android_internal_os_Zygote_nativeForkSystemServer()

说明:通过 SpecializeCommon进行fork,pid返回0时,表示当前为system_server子进程

当pid >0 时,是进入父进程,即Zygote进程,通过waitpid 的WNOHANG 非阻塞方式来监控system_server进程挂掉,如果挂掉后重启Zygote进程。

现在使用的Android系统大部分情况下是64位的,会存在两个Zygote,当system_server挂掉后,只启动Zygote64这个父进程

源码:


static jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities) { pid_t pid = ForkCommon(env, true, fds_to_close, fds_to_ignore); if (pid == 0) { //进入子进程 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true, false, nullptr, nullptr); } else if (pid > 0) { //进入父进程,即zygote进程 ALOGI("System server process %d has been created", pid); int status; //用waitpid函数获取状态发生变化的子进程pid //waitpid的标记为WNOHANG,即非阻塞,返回为正值就说明有进程挂掉了 if (waitpid(pid, &status, WNOHANG) == pid) { //当system_server进程死亡后,重启zygote进程 ALOGE("System server process %d has died. Restarting Zygote!", pid); RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!"); } ... } return pid;}



4.1.5 [com_android_internal_os_Zygote.cpp] ForkCommon

说明:从Zygote孵化出一个进程的使用程序

源码:


static pid_t ForkCommon(JNIEnv* env, bool is_system_server, const std::vector<int>& fds_to_close, const std::vector<int>& fds_to_ignore) { //设置子进程的signal SetSignalHandlers(); //在fork的过程中,临时锁住SIGCHLD BlockSignal(SIGCHLD, fail_fn); //fork子进程,采用copy on write方式,这里执行一次,会返回两次 //pid=0 表示Zygote fork SystemServer这个子进程成功 //pid > 0 表示SystemServer 的真正的PID pid_t pid = fork(); if (pid == 0) { //进入子进程 // The child process. PreApplicationInit(); // 关闭并清除文件描述符 // Clean up any descriptors which must be closed immediately DetachDescriptors(env, fds_to_close, fail_fn); ... } else { ALOGD("Forked child process %d", pid); } //fork结束,解锁 UnblockSignal(SIGCHLD, fail_fn); return pid;}



4.1.6 [Zygcom_android_internal_os_Zygoteote.cpp] SpecializeCommon

说明:system_server进程的一些调度配置

源码:


static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities, jint mount_external, jstring managed_se_info, jstring managed_nice_name, bool is_system_server, bool is_child_zygote, jstring managed_instruction_set, jstring managed_app_data_dir) { ... bool use_native_bridge = !is_system_server && instruction_set.has_value() && android::NativeBridgeAvailable() && android::NeedsNativeBridge(instruction_set.value().c_str()); if (!is_system_server && getuid() == 0) { //对于非system_server子进程,则创建进程组 const int rc = createProcessGroup(uid, getpid()); if (rc == -EROFS) { ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?"); } else if (rc != 0) { ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc)); } } SetGids(env, gids, fail_fn); //设置设置group SetRLimits(env, rlimits, fail_fn); //设置资源limit if (use_native_bridge) { // Due to the logic behind use_native_bridge we know that both app_data_dir // and instruction_set contain values. android::PreInitializeNativeBridge(app_data_dir.value().c_str(), instruction_set.value().c_str()); } if (setresgid(gid, gid, gid) == -1) { fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno))); } ... //selinux上下文 if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) { fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid, is_system_server, se_info_ptr, nice_name_ptr)); } //设置线程名为system_server,方便调试 if (nice_name.has_value()) { SetThreadName(nice_name.value()); } else if (is_system_server) { SetThreadName("system_server"); } // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers). //设置子进程的signal信号处理函数为默认函数 UnsetChldSignalHandler(); if (is_system_server) {
//对应 Zygote.java 的callPostForkSystemServerHooks() env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks); if (env->ExceptionCheck()) { fail_fn("Error calling post fork system server hooks."); } //对应ZygoteInit.java 的 createSystemServerClassLoader() //预取系统服务器的类加载器。这样做是为了尽早地绑定适当的系统服务器selinux域。 env->CallStaticVoidMethod(gZygoteInitClass, gCreateSystemServerClassLoader); if (env->ExceptionCheck()) { // Be robust here. The Java code will attempt to create the classloader // at a later point (but may not have rights to use AoT artifacts). env->ExceptionClear(); } ... } //等价于调用zygote.java 的callPostForkChildHooks() env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags, is_system_server, is_child_zygote, managed_instruction_set); if (env->ExceptionCheck()) { fail_fn("Error calling post fork hooks."); }}



4.1.7 [ZygoteInit.java] handleSystemServerProcess

说明:创建类加载器,并赋予当前线程,其中环境变量SYSTEMSERVERCLASSPATH,主要是service.jar、ethernet-service.jar和wifi-service.jar这三个jar包

export SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar

源码:


private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) { if (parsedArgs.mNiceName != null) { Process.setArgV0(parsedArgs.mNiceName); //设置当前进程名为"system_server" } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { //执行dex优化操作 if (performSystemServerDexOpt(systemServerClasspath)) { sCachedSystemServerClassLoader = null; } ... } if (parsedArgs.mInvokeWith != null) { String[] args = parsedArgs.mRemainingArgs; //如果我们有一个非空系统服务器类路径,我们将不得不复制现有的参数并将类路径附加到它。 //当我们执行一个新进程时,ART将正确地处理类路径。 if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2]; amendedArgs[0] = "-cp"; amendedArgs[1] = systemServerClasspath; System.arraycopy(args, 0, amendedArgs, 2, args.length); args = amendedArgs; } //启动应用进程 WrapperInit.execApplication(parsedArgs.mInvokeWith, parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion, VMRuntime.getCurrentInstructionSet(), null, args); throw new IllegalStateException("Unexpected return from WrapperInit.execApplication"); } else { // 创建类加载器,并赋予当前线程 createSystemServerClassLoader(); ClassLoader cl = sCachedSystemServerClassLoader; if (cl != null) { Thread.currentThread().setContextClassLoader(cl); }  //system_server进入此分支       return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,               parsedArgs.mRemainingArgs, cl);   }}

      



4.1.8 [ZygoteInit.java] zygoteInit

说明:基础配置,并进行应用初始化,返回对象

源码:


public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit"); RuntimeInit.redirectLogStreams(); //重定向log输出 RuntimeInit.commonInit(); //通用的一些初始化 ZygoteInit.nativeZygoteInit(); // zygote初始化 // 应用初始化 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);}



4.1.9 [RuntimeInit.java] commonInit

说明:配置log、时区、http userAgent等基础信息

源码:


protected static final void commonInit() { LoggingHandler loggingHandler = new LoggingHandler();
// 设置默认的未捕捉异常处理方法 RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler); Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler)); // 设置时区,通过属性读出中国时区为"Asia/Shanghai" RuntimeHooks.setTimeZoneIdSupplier(() -> SystemProperties.get("persist.sys.timezone")); //重置log配置 LogManager.getLogManager().reset(); new AndroidConfig(); //设置默认的HTTP User-agent格式,用于 HttpURLConnection String userAgent = getDefaultUserAgent(); System.setProperty("http.agent", userAgent); /* * Wire socket tagging to traffic stats. */ //设置socket的tag,用于网络流量统计 NetworkManagementSocketTagger.install(); ...}


4.1.10 [ZygoteInit.java] nativeZygoteInit

说明:nativeZygoteInit 通过反射,进入com_android_internal_os_ZygoteInit_nativeZygoteInit

源码:


[AndroidRuntime.cpp]int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env){ const JNINativeMethod methods[] = { { "nativeZygoteInit", "()V", (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit }, }; return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit", methods, NELEM(methods));}gCurRuntime = this;static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz){ //此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的 gCurRuntime->onZygoteInit();}


[app_main.cpp]

virtual void onZygoteInit(){ sp<ProcessState> proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); //启动新binder线程}



4.1.11 [RuntimeInit.java] applicationInit

说明:通过参数解析,得到args.startClass = com.android.server.SystemServer

源码:


protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用 nativeSetExitWithoutCleanup(true); // We want to be fairly aggressive about heap utilization, to avoid // holding on to a lot of memory that isn't needed.
//设置虚拟机的内存利用率参数值为0.75 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args = new Arguments(argv); //解析参数 ...   // Remaining arguments are passed to the start class's static main   //调用startClass的static方法 main() return findStaticMain(args.startClass, args.startArgs, classLoader);
}




4.1.12 [RuntimeInit.java] findStaticMain

说明:拿到SystemServer的main()方法,并返回 MethodAndArgsCaller()对象

源码:


protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { Class<?> cl; try { //拿到com.android.server.SystemServer 的类对象 cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } Method m; try { //得到SystemServer的main()方法, 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); } //把MethodAndArgsCaller的对象返回给ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率    //清除了设置进程所需的所有堆栈帧 return new MethodAndArgsCaller(m, argv);
}




4.1.13 [RuntimeInit.java] MethodAndArgsCaller

说明:最终在ZygoteInit.java的main(),调用这里的run()来启动SystemServer.java的main(),真正进入SystemServer进程

源码:


static class MethodAndArgsCaller implements Runnable { /** method to call */ private final Method mMethod; /** argument array */ private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } 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); } }}




下一节会讲解SystemServer 启动的流程以及不同阶段的服务启动,欢迎继续关注

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存