android 开机启动流程分析(12)SystemServer启动分析

198 篇文章 98 订阅

该系列文章总纲链接:专题总纲目录 Android Framework 总纲


本章关键点总结 & 说明:

这里因为整体的导图太大,因此截取一部分 ,方便大家看的清楚:

同时,下面的图是开机启动流程分析 持续迭代的效果,可放大观看。

说明:思维导图是基于之前文章不断迭代的,本章内容我们关注➕"启动SystemServer ->SS"部分即可

1 SS创建

1.1 SS fork进程

SystemServer的进程名实际上叫system_server(后简称为SS)。SS是由Zygote通过Zygote.forkSystemServer函数fork诞生出来的。forkSystemServer的实现(java部分)代码如下:

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    VM_HOOKS.preFork();
	/**
	 nativeForkSystemServer{java->native调用关联}
	 ->com_android_internal_os_Zygote_nativeForkSystemServer//接下来关键分析该方法
	 */
    int pid = nativeForkSystemServer(
            uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
    VM_HOOKS.postForkCommon();
    return pid;
}

native层对应实现方法com_android_internal_os_Zygote_nativeForkSystemServer,代码如下:

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一个子进程
	pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,debug_flags, rlimits,permittedCapabilities, effectiveCapabilities,
										MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,NULL, NULL);
	if (pid > 0) {
		gSystemServerPid = pid;    //保存system_server的进程id
		int status;
		if (waitpid(pid, &status, WNOHANG) == pid) {    //函数退出前须先检查刚创建的子进程是否退出了
			RuntimeAbort(env);    //如果system_server退出了,Zygote直接干掉了自己
		}
	}
	return pid;
}

继续分析ForkAndSpecializeCommon,实现如下:

static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid,...) {
	uint64_t start = MsTime();
	/**
	  SetSigChldHandler
	  ->sigaction(SIGCHLD, &sa, NULL);//设置信号处理函数sigchldHandler
	  {该信号是子进程死亡的信号,进程死亡会执行对应的信号处理函数}
	  -->sigchldHandler处理信号{
		while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
			...
			if (pid == gSystemServerPid) {//如果死去的子进程是SS,则Zygote把自己也杀死了
				kill(getpid(), SIGKILL);
			}
		}
	  }
	 */
	SetSigChldHandler();
	ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler");
	pid_t pid = fork();
	if (pid == 0) {//子进程初始化操作
		//对子进程要根据传入的参数做一些处理,例如设置进程名,设置各种id(用户id,组id等)
		...
	} else if (pid > 0) {
		//父进程相关操作
		...
	}
	return pid;//注意,这里也意味着有两个返回值
}

1.2 SystemServer创建过程

SS创建后,便和生父Zygote分开处理,它有了自己的历史使命。
startSystemServer中在子进程SS中最关键调用为handleSystemServerProcess来承担自己的职责。代码实现如下:

//startSystemServer->handleSystemServerProcess
private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller {
    closeServerSocket();//因为当前已经不是运行在zygote进程里了,所以zygote里的那个监听socket就应该关闭了
    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);//设置进程名为niceName,也就是"system_server"
    }
    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        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);
        }
        //设置SS进程的一些参数
        WrapperInit.execApplication(parsedArgs.invokeWith,parsedArgs.niceName, parsedArgs.targetSdkVersion,null, args);
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
            Thread.currentThread().setContextClassLoader(cl);
        }
        //调用ZygoteInit函数
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }
}

SS走到RuntimeInit了,它的代码实现如下所示:

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    redirectLogStreams();//重定向Log输出流。
    commonInit();//做一些常规初始化。{时区,网络,日志}
    nativeZygoteInit();//native层的初始化,关键点1
    applicationInit(targetSdkVersion, argv, classLoader);//应用初始化,关键点2
}

 1.2.1 nativeZygoteInit的调用栈,代码实现如下:

/**
  nativeZygoteInit{java->native调用关联}
  ->com_android_internal_os_RuntimeInit_nativeZygoteInit
  -->gCurRuntime->onZygoteInit();//app_process的main函数中的runtime
  {gCurRuntime类型为AppRuntime,由于SS是从Zygote fork出来的,所以它拥有Zygote进程的gCurRuntime}
  {AppRuntime继承AndroidRuntime,初始化时会执行gCurRuntime = this;的操作,即gCurRuntime被设置为AndroidRuntime对象自己}
*/

分析gCurRuntime->onZygoteInit()的实现(定要在App_main.cpp中)如下:

virtual void onZygoteInit()
{
    //这些和Binder有关系
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool();/启动一个线程,用于Binder通信。
}

SS调用zygoteInitNative后,将和Binder通信系统建立联系,这样SS就能够使用Binder了。

1.2.2 applicationInit的分析,代码实现如下:

private static void applicationInit(int targetSdkVersion, 
        String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    nativeSetExitWithoutCleanup(true);
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
    final Arguments args;
    args = new Arguments(argv);
	...//异常处理
    //这里注意:startClass名为"com.android.server.SystemServer"
    invokeStaticMain(args.startClass,args.startArgs, classLoader);
}

这里分析关键代码invokeStaticMain,实现如下:

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
    //注意我们的参数,className为"com.android.server.SystemServer"
    Class<?> cl = Class.forName(className, true, classLoader);
    ...//异常处理
    //找到com.android.server.SystemServer类的main函数,肯定有地方要调用它
    Method m;        
    m = cl.getMethod("main", new Class[] { String[].class });
    
    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException("Main method is not public and static on " + className);
    }
    //抛出一个异常,为什么不在这里直接调用上面的main函数呢?后面会给出答案
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

invokeStaticMain竟然抛出了一个异常,它是在ZygoteInit的main函数中截获。

代码如下(注意:我们所在的进程是system_server):

 ... 
    //接着ZygoteInit中第5个关键点继续分析
    ...
         if (startSystemServer) { //我们传入的参数满足if分支,这里是可能抛出异常的
             startSystemServer(abiList, socketName);//该方法最后抛出一个异常MethodAndArgsCaller
         }
    ...
     } catch (MethodAndArgsCaller caller) {
	     /**
		  caller的run方法
          mMethod.invoke(null, new Object[] { mArgs });
		  {mMethod为com.android.server.SystemServer的main函数}
		  {抛出的这个异常最后会导致com.android.server.SystemServer类的main函数被调用}
		 */
         caller.run();    //关键点5,被截获,调用caller的run函数
     } catch (RuntimeException ex) {
         Log.e(TAG, "Zygote died with exception", ex);
         closeServerSocket();
         throw ex;
     }

说明:

  1. 父进程Zygote在fork动作后,会退出startSystemServer()函数,并走到runSelectLoop(),从而进入一种循环监听状态,每当AMS向它发出“启动新应用进程”的命令时,它又会fork一个子进程,并在子进程里抛出一个异常,这样还是会跳转到catch这里。
  2. fork出的SystemServer进程在跳转到catch语句后,会执行SystemServer类的main()函数,而其他情况下,fork出的应用进程在跳转的catch语句后,则会执行ActivityThread类的main()函数。这个ActivityThread对于应用程序而言非常重要
  3. 为什么不在invokeStaticMain那里直接调用,而是采用这种抛异常的方式?这是因为:这个调用是在ZygoteInit.main中,相当于Native的main函数,即入口函数,位于堆栈的顶层。如果不采用抛异常的方式,而是在invokeStaticMain那里调用,则会浪费之前函数调用所占用的一些调用堆栈。这是从效率上来考虑的(由于是系统层的设计,一点点的效率都不可以忽视)

整个过程目的:ZygoteInit分裂产生的SS,其实就是为了调用com.android.server.SystemServer的main函数。

2 SS启动

这里直接查看run的实现,代码如下:

//main->new SystemServer().run();
private void run() {
    ...// 检测时间设置
    ...// 启动性能分析采样
	...
    // Within the system server, it is an error to access Environment paths without explicitly specifying a user.
    Environment.setUserRequired(true);
    // Ensure binder calls into the system always run at foreground priority.
    BinderInternal.disableBackgroundScheduling(true);
    // Prepare the main looper thread (this thread).
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
    ...
    Looper.prepareMainLooper();    //准备主线程循环
    // Initialize native services.
    System.loadLibrary("android_servers"); //加载libandroid_servers.so,源码在framework/base/services/jni下。
    nativeInit();//调用native函数,关键点1
    ...
    performPendingShutdown();// Check whether we failed to shut down last time we tried.This call may not return.
    createSystemContext();//初始化系统上下文,关键点2
    // Create the system service manager.
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    // 启动服务
    try {
        startBootstrapServices();//启动BootStrap相关服务,关键点3
        startCoreServices();//启动核心服务,关键点4
        startOtherServices();//启动其他服务,关键点5
    } catch (Throwable ex) {           /// M: RecoveryManagerService  @{
        if (mRecoveryManagerService != null && ex instanceof RuntimeException) {
            mRecoveryManagerService.handleException((RuntimeException)ex, true);
        }
    }
    ...
    addBootEvent(new String("Android:SysServerInit_END"));
    // Loop forever.
    Looper.loop();// 启动线程循环,等待消息处理
    throw new RuntimeException("Main thread loop unexpectedly exited");//不应该执行到这里
}

2.1 native_init调用栈如下:

/**
  nativeInit{java->native调用关联}
  ->android_server_SystemServer_nativeInit
  -->property_get("system_init.startsensorservice", propBuf, "1");
  -->if (strcmp(propBuf, "1") == 0){SensorService::instantiate();}
  {通过属性确定SensorService是否启动}
 */

2.2 关注createSystemContext,代码实现如下:

private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}

这里主要就是初始化mSystemContext成员变量。

2.3 启动各种各样的服务

2.3.1 startBootstrapServices();//引导服务,使系统可以正常工作的必要服务,这些服务具有复杂的相互依赖性

private void startBootstrapServices() {
	//服务必须提前加载的原因
	//installd完成启动它才有一个机会用适当的方法创建关键的目录,如数据/用户权限。
    Installer installer = mSystemServiceManager.startService(Installer.class);
    //AMS是核心显示相关
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
	//PowerMS很多服务需要使用它,被native daemon监听并很快处理binder回调
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
	//AMS关联PowerMS
    mActivityManagerService.initPowerManagement();
	//为PackageMS初始化准备
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    // Only run "core" apps if we're encrypting the device.
    String cryptState = SystemProperties.get("vold.decrypt");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        Slog.w(TAG, "Device encrypted - only parsing core apps");
        mOnlyCore = true;
    }
	//PackageMS启动初始化
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();
    ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
    //用attribute cache来初始化packages的cache resources
    AttributeCache.init(mSystemContext);
    //为系统进程设置应用程序实例且启动
    mActivityManagerService.setSystemProcess();
}

2.3.2 startCoreServices();     //核心服务,启动一些不在引导过程中的一些基本服务。

private void startCoreServices() {
    // Manages LEDs and display backlight.
    mSystemServiceManager.startService(LightsService.class);
    // Tracks the battery level.  Requires LightService.
    mSystemServiceManager.startService(BatteryService.class);
    // Tracks application usage stats.
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));
			
    // Update after UsageStatsService is available, needed before performBootDexOpt.
    mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
    // Tracks whether the updatable WebView is in a ready state and watches for update installs.
    mSystemServiceManager.startService(WebViewUpdateService.class);
}

2.3.3 startOtherServices();    //其他服务,一般添加服务都在这里添加{所有其他的java系统服务都在这里启动}

private void startOtherServices() {
    final Context context = mSystemContext;
    AccountManagerService accountManager = null;
    ...
    AudioService audioService = null;
    MmsServiceBroker mmsService = null;
    ...
    try {
        Slog.i(TAG, "Reading configuration...");
        SystemConfig.getInstance();
        Slog.i(TAG, "Scheduling Policy");
        ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
        mSystemServiceManager.startService(TelecomLoaderService.class);
	...
    try {
        wm.displayReady();
    } catch (Throwable e) {
        reportWtf("making display ready", e);
    }
	...
    mActivityManagerService.systemReady(new Runnable() {
        @Override
        public void run() {
            Slog.i(TAG, "Making services ready");
            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
			...
            try {
                mActivityManagerService.startObservingNativeCrashes();
            } catch (Throwable e) {
                reportWtf("observing native crashes", e);
            }
			...
        }
    });
}

2.4 总结

在这个run方法中,主要完成三件事情:

  1. 创建system context和system service manager
  2. 启动一些系统服务
  3. 进入主线程消息循环。

2.5 SS整体总结

    Zygote调用startSystemServer创建system_server进程
    SS调用handleSystemServerProcess完成自己的使命
    handleSystemServerProcess抛出异常,最终调用com.android.server.SystemServer的main函数
    main加载libandroid_server.so并调用native_init方法
    在后面的3个关键方法中,启动一些系统服务
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
    进入消息循环,等待请求

说明:启动系统各项服务,Java世界的核心Service都在这里启动,所以它非常重要。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图王大胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值