Android系统启动流程

前言

本文主要讲述android系统从开机到显示出Launcher界面的整个大致流程.以方便大家有个整体的流程认识,不会对细节部分讲解. 细节部分后面将会慢慢讲. 此外本文以及后面的所有文章android源码版本是android-9.0.0_r3 .

启动流程简述

android系统启动从底层到上层依次为 1. Boot Rom  2. Bootloader  3. 内核kernel 4. init  5. Zygote  6. ART虚拟机  

7. SystemServer  8.  各个Manager  9. HomeActivity

1. Boot Rom

引导芯片开始从固化在ROM的预设代码开始执行,然后加载引导程序到RAM

2. Bootloader

引导程序,其最终的目的就是拉起操作系统. 其初始化最低的相关硬件环境后会将内核加载进内存.

3. kernel

内核加载进内存后,先进入内核引导阶段,在内核引导阶段最后,调用start_kernel进入内核启动阶段,主要是完成内核的大部分初始化工作。start_kernel会最终启动用户空间的init进程

4. init进程

init是一个非常非常重要的进程其进程ID为0  该程序就在 android系统根目录下面. 其在aosp中源码目录是 system/core/init 下面.

init进程负责创建系统中最为核心的几个守护进程,如: Zygote,  servicemanager 

解析init.rc文件来启动相关的service服务. 挂载并创建相关的文件,启动相关的进程服务,

该进程还提供很重要的property服务, 其核心代码在property_service.cpp中. 这个会在其它文章中讲述. 其中Zygote 进程也是通过解析init.rc 文件来启动的

开机动画也是通过解析init.rc来启动surfaceflinger服务(代码在frameworks/native/services/surfaceflinger),surfaceflinger来通过startBootAnim() 

 

5. Zygote进程

init.rc文件中有这么一句import /init.${ro.zygote}.rc    ${ro.zygote} 实际可对应到 init.zygote32.rc, init.zygote64.rc, init.zygote64_32.rc, init.zygote32_64.rc,前两个只会启动单一app_process(64) 进程,而后两个则会启动两个app_process进程:第二个app_process进程称为 secondary.  至于rc文件的详细意思会在其它的文章中去详细讲解. 现在只需要知道 通过解析这几个文件来启动对应的Zygote进程. 其对应的代码是以下核心文件

/frameworks/base/cmds/app_process/app_main.cpp
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

我们可以看看 app_main.cpp文件的最后几句代码

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }

根据入口参数,我们知道 zygote 为true,args参数中包含了”start-system-server”

runtime 也就是 AppRuntime 是继承自 AndroidRuntime,因此下一步就执行到 AndroidRuntime 的 start 函数. 代码在

frameworks/base/core/jni/AndroidRuntime.cpp 其中有下面的代码段

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
            className != NULL ? className : "(unknown)", getuid());

    static const String8 startSystemServer("start-system-server");

    /*
     * 'startSystemServer == true' means runtime is obsolete and not run from
     * init.rc anymore, so we print out the boot start event here.
     */
    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
           /* track our progress through the boot sequence */
           const int LOG_BOOT_PROGRESS_START = 3000;
           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  
           ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
    }

    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
    //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

    /* start the virtual machine */
    // 创建虚拟机,其中大多数参数由系统属性决定
    // 最终,startVm利用JNI_CreateJavaVM创建出虚拟机
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

上面代码最后就是创建虚拟机. 这是 该start函数做的一件事. 另外还有一件事就是调用传入类名对应类的 main 函数,即 调用 

com.android.internal.os.ZygoteInit.java 类的main函数代码片段在 onVmCreated(env) 后面在此不予贴出来,各位可以自行去源码中对应的目录查看.

6. ART虚拟机

我们都知道Google在Android4.4开始引入了 ART , 即运行时编译Android Runtime,是一种在Android操作系统上的运行环境,在Android 5.0及后续Android版本中作为正式的运行时库取代了以往的Dalvik虚拟机。ART能够把应用程序的字节码转换为机器码,是Android所使用的一种新的虚拟机。它与Dalvik的主要不同在于:Dalvik采用的是JIT技术,而ART采用Ahead-of-time(AOT)技术。ART同时也改善了性能、垃圾回收(Garbage Collection)、应用程序除错以及性能分析.

而在我们安装应用程序的过程中,ART就已经将所有的字节码重新编译成了机器码。程序运行过程中无需进行实时的编译工作,只需要进行直接调用。因此ART极大的提高了应用程序的运行效率.

在上面 Zygote 进程中我们已经知道了 虚拟机创建的时机以及相应的入口,具体的细节会后续其它文章进行讲述. 

7. SystemServer

在第5部分最后说明了 AndroidRuntime.cpp 中的 start函数将会调用传入类名对应类的 main 函数,即 调用 

com.android.internal.os.ZygoteInit.java 类的main函数. 我们现在看看 ZygoteInit.java的 main函数

 public static void main(String argv[]) {
        //创建ZygoteServer对象
        ZygoteServer zygoteServer = new ZygoteServer();

        // 调用native函数,确保当前没有其它线程在运行
        // 主要还是处于安全的考虑
        ZygoteHooks.startZygoteNoThreadCreation();

        // Zygote goes into its own process group.
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        final Runnable caller;
        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());
            }

            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
            TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                    Trace.TRACE_TAG_DALVIK);
            bootTimingsTraceLog.traceBegin("ZygoteInit");
            RuntimeInit.enableDdms();

            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            
            // 解析参数,得到上述变量的值
            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.");
            }

            zygoteServer.registerServerSocketFromEnv(socketName);
            // In some configurations, we avoid preloading resources and classes eagerly.
            // In such cases, we will preload things prior to our first fork.
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                preload(bootTimingsTraceLog);   //预加载信息
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                 // 如注释,延迟预加载 变更Zygote进程优先级为NORMAL级别 第一次fork时才会preload
                 Zygote.resetNicePriority();
            }

            // Do an initial gc to clean up after startup
            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
            gcAndFinalize();
            bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

            bootTimingsTraceLog.traceEnd(); // ZygoteInit
            // Disable tracing so that forked processes do not inherit stale tracing tags from
            // Zygote.
            Trace.setTracingEnabled(false, 0);

            Zygote.nativeSecurityInit();

            // Zygote process unmounts root storage spaces.
            Zygote.nativeUnmountStorageOnInit();

            ZygoteHooks.stopZygoteNoThreadCreation(); // 允许有其它线程

            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
                // child (system_server) process.
                if (r != null) {
                    r.run();    // 启动 system_server
                    return;
                }
            }

            Log.i(TAG, "Accepting command socket connections");

            // The select loop returns early in the child process after a fork and
            // loops forever in the zygote.
            caller = zygoteServer.runSelectLoop(abiList);   // zygote进程进入无限循环,处理请求
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            zygoteServer.closeServerSocket();
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
            caller.run();
        }
    }
  private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_IPC_LOCK,
            OsConstants.CAP_KILL,
            OsConstants.CAP_NET_ADMIN,
            OsConstants.CAP_NET_BIND_SERVICE,
            OsConstants.CAP_NET_BROADCAST,
            OsConstants.CAP_NET_RAW,
            OsConstants.CAP_SYS_MODULE,
            OsConstants.CAP_SYS_NICE,
            OsConstants.CAP_SYS_PTRACE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG,
            OsConstants.CAP_WAKE_ALARM,
            OsConstants.CAP_BLOCK_SUSPEND
        );
        /* Containers run without some capabilities, so drop any caps that are not available. */
        StructCapUserHeader header = new StructCapUserHeader(
                OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
        StructCapUserData[] data;
        try {
            data = Os.capget(header);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to capget()", ex);
        }
        capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);

        /* 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,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",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);  // 将上面准备的参数,按照ZygoteConnection的风格进行封装
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            boolean profileSystemServer = SystemProperties.getBoolean(
                    "dalvik.vm.profilesystemserver", false);
            if (profileSystemServer) {
                parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }

            /* // 通过fork分裂出system_server */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.runtimeFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
             // 处理32_64和64_32的情况
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            // fork时会copy socket,system server需要主动关闭
            zygoteServer.closeServerSocket();
            
             system server进程处理自己的工作
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }

创建出SystemServer进程后,zygote进程将会调用ZygoteServer中的函数runSelectLoop,处理server socket收到的命令.

上面的代码中有注释到 通过fork分裂出system_server.   源码frameworks/base/services/java/com/android/server/SystemServer.java

几乎所有的服务都在该进程中, 如: ActivityManagerService, PowerMangerService.

8. 各个Manager

通过 SystemServer.java的源码其实我们就可以看出来 各个核心的ManagerService都在这里, 这里将不再详细说明.各位可以重点看看ActivityManagerService

9. 启动Launcher

在SystemServer.java中有这么一段代码


        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.该段注释意思就是可以启动第三方的程序了
        mActivityManagerService.systemReady(() -> {
            Slog.i(TAG, "Making services ready");
            traceBeginAndSlog("StartActivityManagerReadyPhase");
            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
            traceEnd();
            traceBeginAndSlog("StartObservingNativeCrashes");
            try {
                mActivityManagerService.startObservingNativeCrashes();
            } catch (Throwable e) {
                reportWtf("observing native crashes", e);
            }
            traceEnd();

我们进入到 ActivityManagerService中的 systemReady(final Runnable goingCallback, TimingsTraceLog traceLog)方法

 源码的位置在frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 在 systemReady 方法中调用了 这么一个方法 startHomeActivityLocked(currentUserId, "systemReady"); 

 而startHomeActivityLocked的方法中 又调用了 getHomeIntent() 方法. getHomeIntent的具体实现如下:

 Intent getHomeIntent() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : 
                            null);
        intent.setComponent(mTopComponent);
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }

看到代码中的Intent.CATEGORY_HOME 我想各位明白 要启动的Activity是什么了吧?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值