阅读 5124

Android 系统启动流程

Android系统是基于Linux定制的一款开源的而移动端操作系统,由于其开源的特性,各大手机厂商可以针对其源码进行深度定制,对于开发者来说,有如此庞大且优秀的开源os提供参考,尤其是对移动端的开发者来说,阅读Android系统源码可以帮助我们更好地理解其中的各种机制,平时束手无策的问题也可以在源码中寻找答案。当然光8.0的源码就20多个g,像全部读完几乎是不可能的事,我们主要以framework为主线,以系统运行机制为分支,层层阅读,剥开Android系统的神秘面纱。

Android 系统架构

首先来一张google经典的Android系统架构图:可以看到,从上到下主要分为4层:应用层,framework层,系统库和运行时,Linux内核层。

这里写图片描述

#Android 启动流程 这里再上一张Android系统启动的流程图,可以看到系统从启动开始是按照一个流程:Loader->kernel->framework->Application来进行的。

这里写图片描述

Loader层:

  • Boot Rom:当手机处于关机状态时,长按开机键开机,会引导芯片开始从固化在Rom里预设的代码开始执行,然后加载引导程序到Ram
  • Boot Loader:启动Android系统之前的引导程序,主要是检查Ram,初始化参数等

Kernel层

Kernel层指的就是Android内核层,这里一般开机刚刚结束进入Android系统,Kernel层的启动流程如下:

  1. 启动swapper进程(pid=0),这是系统初始化过程kernel创建的第一个进程,用于初始化进程管理、内存管理、加载DisplayCameraBinder等驱动相关工作
  2. 启动kthreadd进程,这是Linux系统的内核进程,会创建内核工作线程kworkder、软中断线程ksoftirqdthermal等内核守护进程。kthreadd是所有内核进程的鼻祖。

Native层

这里的native层主要包括由init进程孵化的用户空间的守护进程,bootanim开机动画和hal层等。InitLinux系统的守护进程,是所有用户空间进程的鼻祖。

  • init进程会孵化出ueventdlogdhealthdinstalldadbd、lm这里写代码片kd等用户守护进程;
  • init进程还会启动ServiceManager(Binder服务管家)、bootanim(开机动画)等重要服务。
  • init进程孵化出Zygote进程,Zygote进程是Android系统第一个Java进程(虚拟机进程),Zygote进程是所有Java进程的父进程。

Framework层

framework层有native层和java层共同组成,协调系统平稳有序的工作。framework 层主要包括以下内容:

  • Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlingerCamera Service等服务。
  • Zygote进程,由Init进程通过解析init.rc文件生成,Zygote是Android系统的第一个Java进程,是所有Java进程的父进程。
  • System Server进程,由Zygote进程fork而来,是Zygote进程孵化的第一个子进程,负责启动和管理整个Java Framework,包括AmsPms等。

App层

Zygote进程孵化的第一个App进程是Launcher进程,也就是我们的桌面进程,也就是我们打开手机看到的用户界面。因为在前面的framework 生成了各种守护进程和管理进程,对于Launcher也就有对应的点击、长按、滑动、卸载等监听。Zygote进程也会创建BrowserPhoneEmail等App进程。也就是说所有的App进程都是由Zygote进程fork生成的。而且上层的进程全部由下层的进程进行管理,包括但不限于界面的注册、跳转,消息的传递。

Zygote进程的启动

了解了Android系统从按下开机键到桌面完整运行在用户眼前的整个流程,我们就可以针对系统的各个过程进行分析。由于是移动开发,平时最多打交道的是应用层,也是就上面的App层,跟我们打交道最多的就是framework层,我们主要关注framework层是如何启动并调度各应用进程协调工作的。从ZygoteInitmain方法开始,我们先看framework启动流程的时序图(省略了一些步骤)大体如下:

这里写图片描述

1.ZygoteInit.main

 public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();

        // Mark zygote start. This ensures that thread creation will throw
        // an error.
        ZygoteHooks.startZygoteNoThreadCreation();
		...
        try {
            // Report Zygote start time to tron unless it is a runtime restart
            if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
                MetricsLogger.histogram(null, "boot_zygote_init",
                        (int) SystemClock.elapsedRealtime());
            }
			...
			// 1.加载首个Zygote进程的时候,加载参数有start-system-server,即startSystemServer=true
			
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }

			// 2. 注册zygote服务端localserversocket
            zygoteServer.registerServerSocket(socketName);
	        ...
			// 3.在这里开启了SystemServer,也就是Ams,Pms,Wms...等一系列系统服务
            if (startSystemServer) {
                startSystemServer(abiList, socketName, zygoteServer);
            }
            Log.i(TAG, "Accepting command socket connections");
            
			// 4.while(true) 死循环,除非抛出异常系统中断
            zygoteServer.runSelectLoop(abiList);
            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }
复制代码

ZygoteInit.main()native层传入初始化参数调用,这里不再赘述,这边主要沿Java的framework层来分析系统的调用,结合上图和代码注释可以看到,加载参数有start-system-server,即startSystemServer=true赋值,紧接着下面会调用ZygoteServer.registerServerSocket(),也就是这里和ZygoteServer的通信用到的是LocalSocket,我们知道跨进程调用最常见的调用方式就是LocalSocketaidl,在framework里也有很多这样通信的。接下来就开启了SystemServer,后面是一个runSelectLoop(),这里其实是一个死循环,当抛出异常终止则会调用zygoteServer.closeServerSocket()来关闭socket连接。我们继续跟进startSystemServer看具体是如何开启系统服务的。

2.startSystemServer

    /**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {
        ...
        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
	        //传入准备参数,注意上面参数最后的"com.android.server.SystemServer"
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

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

        /* For child process */
		
		// pid = 0 说明创建子进程成功,SystemServer此时拥有独立进程,可以独立在自己的进程内操作了
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            // 处理SystemServer进程
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }
复制代码

这个方法不是很长,看注释可以知道,主要是用来准备SystemServer进程的参数和forkSystemServer进程。前面一堆参数不用看,注意我添加中文注释的地方,传入的参数有一个内容为"com.android.server.SystemServer",这是SystemServer类的全限定名,接下来调用Zygote.forkSystemSeerver(),最后当pid=0时,也就是说明子进程创建成功,如果这时候有两个Zygote进程则等待第二个Zygote进程连接,关闭掉第一个Zygote进程和ZygoteServersocket连接。最后调用handleSystemServerProcess()来处理SystemServer进程。这里的Zygote.forkSystemServer()实际上是调用了native层的forkSystemServer()来fork子进程。这里主要跟进handleSystemServerProcess()看看是如何完成新fork的SystemServer进程的剩余工作的。

3.handleSystemServerProcess

	/**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {
		...
		// 默认为null,走Zygote.init()流程
		
        if (parsedArgs.invokeWith != null) {
            ...
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
	            // 创建类加载器,并赋予当前线程
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
                Thread.currentThread().setContextClassLoader(cl);
            }

            /*
             * Pass the remaining arguments to SystemServer.
             */
            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

        /* should never reach here */
    }
复制代码

parsedArgs.invokeWith默认是为null的,也就是走else流程,可以看到先创建了一个类加载器并赋予了当前线程,然后进入了ZygoteInit.zygoteInit()

4.ZygoteInit.zygoteInit()

    /**
     * The main function called when started through the zygote process. This
     * could be unified with main(), if the native code in nativeFinishInit()
     * were rationalized with Zygote startup.<p>
     *
     * Current recognized args:
     * <ul>
     *   <li> <code> [--] &lt;start class name&gt;  &lt;args&gt;
     * </ul>
     *
     * @param targetSdkVersion target SDK version
     * @param argv arg strings
     */
    public static final void zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
		// Zygote初始化
        ZygoteInit.nativeZygoteInit();
		// 应用初始化
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
复制代码

这个方法不是很长,主要工作是Zygote的初始化和Runtime的初始化。Zygote 的初始化调用了native方法,里面的大致工作是打开/dev/binder驱动设备,创建一个新的binder线程,调用talkWithDriver()不断地跟驱动交互。 进入RuntimeInit.applicationInit()查看具体应用初始化流程。

5.RuntimeInit.applicationInit

    protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        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());
            // let the process exit
            return;
        }

        // The end of of the RuntimeInit event (see #zygoteInit).
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }
复制代码

这个方法也不是很长,前面的一些配置略过,主要看解析参数和invokeStaticMain(),顾名思义,这里的目的是通过反射调用静态的main方法,那么调用的是哪个类的main方法,我们看传入的参数是args.startClass,我们追溯参数的传递过程,发现之前提到的一系列args被封装进ZygoteConnection.Arguments类中,这一系列参数原本是

        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
复制代码

可以看到,唯一的类的全限定名是com.android.server.SystemServer,追述args = new Arguments(argv)的源码也可以找到答案:

		Arguments(String args[]) throws IllegalArgumentException {
            parseArgs(args);
		}

        private void parseArgs(String args[])
                throws IllegalArgumentException {
            int curArg = 0;
            for (; curArg < args.length; curArg++) {
                String arg = args[curArg];

                if (arg.equals("--")) {
                    curArg++;
                    break;
                } else if (!arg.startsWith("--")) {
                    break;
                }
            }

            if (curArg == args.length) {
                throw new IllegalArgumentException("Missing classname argument to RuntimeInit!");
            }

			// startClass 为args的最后一个参数
            startClass = args[curArg++];
            startArgs = new String[args.length - curArg];
            System.arraycopy(args, curArg, startArgs, 0, startArgs.length);
        }
    }
复制代码

6.RuntimeInit.invokeStaticMain

    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.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);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }
复制代码

可以看到,这边走的就是正常的一个反射流程,会对main方法的参数、修饰符等校验,有问题抛出RuntimeException运行时异常,没问题就抛出一个Zygote.MethodAndArgsCaller,这一步的处理可以说是非常奇怪了,既然执行完毕为什么不直接invoke而是抛出异常呢,我们可以看到英文注释的大概解释,这个异常抛出在ZygoteInit.main()方法,执行了异常的run方法,其目的是清除设置中的所有堆栈帧,既然如此我们回到ZygoteInit.main()方法,果然:

	try{
		...
	}catch (Zygote.MethodAndArgsCaller caller) {
        caller.run();
    }
复制代码

抛出该异常调用了caller.run()方法,那我们看这里做了什么:

    public static class MethodAndArgsCaller extends Exception
            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 {
                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);
            }
        }
    }
复制代码

可以看到,这里调用了mMethod.invoke(null, new Object[] { mArgs }),也就是执行了SystemServermain方法。

7.SystemServer.main

    public static void main(String[] args) {
        new SystemServer().run();
    }
复制代码
		try {
			...
			//主线程在当前进程
			Looper.prepareMainLooper();
			...
            // 初始化系统上下文
            createSystemContext();
            
            // 1.创建SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
		} finally {
			traceEnd();
		}
		...
        try {
            traceBeginAndSlog("StartServices");
			//2.开启一些重要的系统服务
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
        ...
        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
复制代码

可以看到,这边主要的工作,创建主线程Looper循环器,初始化系统上下文,最关键的还是后面的开启一系列的服务,这些服务就包括了系统服务,跟进sartBootstrapService()看看是如何初始化系统服务的。

8.SystemServer.startBootstrapServices

		...
		SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
		// 阻塞等待与installd建立socket通道
		Installer installer = mSystemServiceManager.startService(Installer.class);
		// 1. 在这里开启了Ams
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        ...

		// 2.在这里开启了PowerManagerService
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
		
		// 3.Ams 初始化PowerManager
        mActivityManagerService.initPowerManagement();
        
        // Bring up recovery system in case a rescue party needs a reboot
        if (!SystemProperties.getBoolean("config.disable_noncore", false)) {
            traceBeginAndSlog("StartRecoverySystemService");
            // 
            mSystemServiceManager.startService(RecoverySystemService.class);
            traceEnd();
        }
		
		mSystemServiceManager.startService(LightsService.class);
		
		mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
		
		mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        
		mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
		
		mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
		
复制代码

可以看见启动了很多的系统服务,其中很多的服务目前也不是很了解,主要的是ActivityMangerServicePackageManagerService等主要管理系统的一些服务。自此,Android系统的SystemServer已经启动,并且其相关的各种系统服务已经启动,Ams等重要系统服务也均已开启。Ams是贯穿Android系统的核心服务,负责系统四大组件的启动、切换及其生命周期管理和调度等工作,各个应用程序App作为独立进程需要通过BinderAms进行通信,而AmsSystemServer中通过LocalSocketZygote进行通信。不管是对于系统运行的原理,还是各组件的调度过程,理解Ams的工作原理十分重要,接下来将以此为主线,分别分析Ams、四大组件等的启动流程和生命周期的管理等。

参考资料

Android 8.0.1源码

Android系统开篇

Android系统启动过程深入分析