深入Framework层剖析Android系统启动流程

#头条创作挑战赛#

本文从Framework层对 Init进程启动Zygote进程SystemServer进程Launcher进程四部分对安卓系统系统启动流程的完整源码分析。篇幅较长,请耐心阅读!

后续文章逐渐深入Framework层,剖析源码,关注小编,学习不迷路!

简介

当Android手机从按下开机键时,屏幕点亮,到Launcher系统桌面的显示,整个过程系统是怎么启动的?下面我们一起深入源码来看一下。整体流程如下图所示。

源码分析

init进程启动

1.BootROM

当按下电源开关键时,引导芯片程序会从预定义的地方开始执行,加载系统引导程序BootLoader到RAM,启动执行。

2.BootLoader

初始化系统硬件资源,引导操作系统启动。

3.idel进程

初始化进程管理,内存管理,加载Binder驱动,Display,Camera 驱动等相关工作。

4. init进程启动

Main.main()

Android系统启动时 通过Android.bp启动Main.cpp的main函数。

int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
    __asan_set_error_report_callback(AsanReportCallback);
#endif
    // 设置进程优先级
    setpriority(PRIO_PROCESS, 0, -20);
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }

    if (argc > 1) {
        //根据不同的参数 执行不同的函数。
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();

            return SubcontextMain(argc, argv, &function_map);
        }
         //第二次执行 
        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }
        //最后执行到 SecondStageMain
        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }
    //firstStageMain中再次调用main.cpp,参数传为selinux_setup,后续执行SetupSelinux
    return FirstStageMain(argc, argv);

Init.SecondStageMain

Main.cpp的main方法被反复执行,最后执行到init.cp的SecondStageMain方法。

int SecondStageMain(int argc, char** argv) {

    .............
    //初始化属性服务
    PropertyInit();

    // Umount the debug ramdisk after property service has read the .prop files when it means to.
    if (load_debug_prop) {
        UmountDebugRamdisk();
    }

    // Mount extra filesystems required during second stage init
    MountExtraFilesystems();

    // 设置系统安全策略
    SelinuxSetupKernelLogging();
    SelabelInitialize();
    SelinuxRestoreContext();
    //定义epoll机制
    Epoll epoll;
    if (auto result = epoll.Open(); !result.ok()) {
        PLOG(FATAL) << result.error();
    }

    //解析init.rc文件
    LoadBootScripts(am, sm);
   .......................
    while (true) {
        // 循环等待处理
        auto epoll_timeout = std::optional<std::chrono::milliseconds>{};

        auto shutdown_command = shutdown_state.CheckShutdown();
       .........................
     
    }

    return 0;
}

}  // namespace init

SecondStageMain方法中,init进程主要处理:

1)挂载文件,设置系统安全策略。

2)开启属性服务,注册到epoll中。

3)解析init.rc ,启动Zygote进程。


Zygote进程启动

当安卓系统启动后,会创建一个init进程,所以的进程都是这个init进程fork出来的,包括Zygote进程,当系统要求启动一个Android应用程序时,都会通过AMS通知Zygote进程创建一个子进程用来启动该应用程序。

1.App_main.cpp

Zygote进程启动时会执行app_main.cpp的main函数。

int main(int argc, char* const argv[])
{
   .............
   //初始化AppRuntime
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
   
    argc--;
    argv++;
   ...........................

    //是否是zygote进程
    bool zygote = false;
    //是否启动systemServer进程
    bool startSystemServer = false;
    bool application = false;
    //进程名称
    String8 niceName;
    String8 className;

    ++i; 
    while (i < argc) {
        const char* arg = argv[i++];
        //设置zygote启动
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }

    .........................
    
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }

    if (zygote) {
        //如果是zygote进程  执行AppRuntime.start
        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.");
    }
}

2.AndroidRuntime.cpp

AppRuntime继承于AndroidRuntime,执行AppRuntime的start方法就是执行AndroidRuntime中的start方法。className传入的是 "com.android.internal.os.ZygoteInit"。

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
   
    static const String8 startSystemServer("start-system-server");
    //记录当前zygote是否是fork出SystemServer进程
    bool primary_zygote = false;

    
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动虚拟机
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    //如果没有虚拟机则创建新的虚拟机
    onVmCreated(env);

    /*
     * 注册系统jni方法
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    ..................
    /*
     * 启动虚拟机线程,执行ZygoteInit的main方法
     * className :com.android.internal.os.ZygoteInit
     */
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            //执行jni方法 进入:com.android.internal.os.ZygoteInit的main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
    }
    ....................
}

3.ZygoteInit.java

AndroidRuntime.start方法中 通过jni调用java代码,执行com.android.internal.os.ZygoteInit的main方法。

 public static void main(String argv[]) {
        ZygoteServer zygoteServer = null;
        //标记zygote进程启动
        ZygoteHooks.startZygoteNoThreadCreation();
        ...............
        Runnable caller;
        try {
           ...................
            boolean startSystemServer = false;
            String zygoteSocketName = "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)) {
                    zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }
       
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                //预加载资源
                preload(bootTimingsTraceLog);
            }
            //创建zygote服务
            zygoteServer = new ZygoteServer(isPrimaryZygote);
            //通过zygote进程fork出SystemServer进程
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
                if (r != null) {
                    //执行SystemServer的main方法
                    r.run();
                    return;
                } 
            }
            //开启循环
           caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
        } finally {
            if (zygoteServer != null) {
                zygoteServer.closeServerSocket();
            }
        }
    }

ZygoteInit的main方法主要的作用是:

1).预加载系统资源。

2).创建zygote的socket服务。

3).通过Zygote进程fork出SystemServer进程。

4).执行SystemServer的main方法,启动进程。

5).zygote进入循环等待状态,接收AMS传递的消息。

Zygote作为进程孵化器,当需要启动一个程序时,首先会通过AMS使用Socket发送消息到Zygote进程,Zygote通过fork函数创建需要启动的程序进程。


SystemServer进程启动

ZygoteInit通过forkSystemServer创建出SystemServer进程,然后调用SystemServer的run方法进行执行。SystemServer的main方法。

 //通过zygote进程fork出SystemServer进程
 if (startSystemServer) {
     Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
        if (r != null) {
            //执行SystemServer的main方法
            r.run();
          return;
        } 
 }

            

1.SystemServer.java

    /**
     * 从Zygote进程进入SystemServer进程.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
private void run() {
        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
        try {
            ............省略部分代码..............
            //创建当前线程的Looper
            Looper.prepareMainLooper();
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            SystemServiceRegistry.sEnableServiceNotFoundWtf = true;

            //初始化android_servers静态库
            System.loadLibrary("android_servers");
             ..................
            // 创建系统context.
            createSystemContext();

            // 初始化主线程模块
            ActivityThread.initializeMainlineModules();

            // 创建系统服务管理对象-SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // 启动线程池
            SystemServerInitThreadPool.start();
            ...........................
        try {
            t.traceBegin("StartServices");
            startBootstrapServices(t); //启动程序引导服务
            startCoreServices(t); //启动核心服务
            startOtherServices(t);//启动其他服务
        } catch (Throwable ex) {
        } finally {
            t.traceEnd(); // StartServices
        }
         ................

        // 主线程循环等待消息处理.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    


进入SystemServer进程,SystemServer中主要处理以下工作:

1)创建当前线程的Looper。

2) 初始化android_servers静态库。

3)创建系统context。

4)初始化主线程模块。

5)创建系统服务管理对象-SystemServiceManager。

6) 启动线程池。

7) 启动程序引导服务。

8) 启动核心服务。

9) 启动其他服务。

10) 主线程循环等待消息处理。


Launcher启动流程

Launcher作为android系统启动流程的最后一步。它是android系统的桌面程序,在android系统中具有重要作用。用来显示系统已经安装的应用程序。

作用如下:

  1. Launcher作为android系统的启动程序,用于系统程序的启动。
  2. Launcher作为android系统的桌面程序,用于管理和显示已安装的应用程序图标及桌面其他组件。

启动流程分析

1.SystemServer.startOtherServices

SystemServer的main方法中startOtherServices()启动了其他服务,startOtherServices()中就包括了应用程序Launcher的启动。

  private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
       ..............................
        //通过AMS开始启动初始应用程序Launcher
        mActivityManagerService.systemReady(() -> {
            Slog.i(TAG, "Making services ready");
            t.traceBegin("StartActivityManagerReadyPhase");
            mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
            t.traceEnd();
            t.traceBegin("StartObservingNativeCrashes");
            try {
                mActivityManagerService.startObservingNativeCrashes();
            } catch (Throwable e) {
                reportWtf("observing native crashes", e);
            }
            t.traceEnd();
            ..................
}

2.ActivityManagerService.systemReady

在ActivityManagerService中调用systemReady进行系统准备启动工作。

public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
        t.traceBegin("PhaseActivityManagerReady");
        mSystemServiceManager.preSystemReady();
   .....................
    
     t.traceBegin("resumeTopActivities");
            mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
            t.traceEnd();
   .....................
}

systemReady中调用了ActivityTaskManagerService的resumeTopActivities方法,接着看这个resumeTopActivities方法做了哪些工作。

3.ActivityTaskManagerService.resumeTopActivities

 @Override
        public void resumeTopActivities(boolean scheduleIdle) {
            synchronized (mGlobalLock) {
                //进入RootWindowContainer
                mRootWindowContainer.resumeFocusedStacksTopActivities();
                if (scheduleIdle) {
                    mStackSupervisor.scheduleIdle();
                }
            }
        }

在ActivityTaskManagerService中调用RootWindowContainer的resumeFocusedStacksTopActivities方法。

4.RootWindowContainer.resumeFocusedStacksTopActivities

   
//第一次进入    
boolean resumeFocusedStacksTopActivities() {
        return resumeFocusedStacksTopActivities(null, null, null);
    }
   //入参都为null
    boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        if (!mStackSupervisor.readyToResume()) {
            return false;
        }
        .........................
            if (!resumedOnDisplay) {
                final ActivityStack focusedStack = display.getFocusedStack();
                if (focusedStack != null) {
                    result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
                } 
                //首次启动Launcher,入参为null
                else if (targetStack == null) {
                    //启动homeActivity
                    result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                            display.getDefaultTaskDisplayArea());
                }
            }
    
        return result;
    }

系统首次启动时,调用resumeFocusedStacksTopActivities传入的参数都为nul,然后通过if判断targetStack==null为true,调用resumeHomeActivity方法进行homeActivity启动。

5.RootWindowContainer.resumeHomeActivity

boolean resumeHomeActivity(ActivityRecord prev, String reason,
            TaskDisplayArea taskDisplayArea) {
        //服务是否已经启动
        if (!mService.isBooting() && !mService.isBooted()) {
            return false;
        }

        .....
        //从任务栈中获取HomeActivity
        final ActivityRecord r = taskDisplayArea.getHomeActivity();
        final String myReason = reason + " resumeHomeActivity";

        // 已经启动过了
        if (r != null && !r.finishing) {
            r.moveFocusableActivityToTop(myReason);
            return resumeFocusedStacksTopActivities(r.getRootTask(), prev, null);
        }
        //首次启动
        return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea,
                false /* allowInstrumenting */, false /* fromHomeKey */);
    }

在resumeHomeActivity方法中,判断服务是已经初始化完成,通过ActivityRecord任务栈获取HomeActivty,如果已经启动过则直接从任务栈中恢复,否则启动新的HomeActivity,这里系统是首次启动,进入startHomeOnTaskDisplayArea执行。

6.RootWindowContainer.startHomeOnTaskDisplayArea

 boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
            boolean allowInstrumenting, boolean fromHomeKey) {
        // 创建显示区域
        if (taskDisplayArea == null) {
            final ActivityStack stack = getTopDisplayFocusedStack();
            taskDisplayArea = stack != null ? stack.getDisplayArea()
                    : getDefaultTaskDisplayArea();
        }

        Intent homeIntent = null;
        ActivityInfo aInfo = null;
        if (taskDisplayArea == getDefaultTaskDisplayArea()) {
            //创建Intent
            homeIntent = mService.getHomeIntent();
            aInfo = resolveHomeActivity(userId, homeIntent);
        } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
            Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
            aInfo = info.first;
            homeIntent = info.second;
        }
        //更新Intent启动信息
        homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
        homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
        //启动HomeActivity
        mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
                taskDisplayArea);
        return true;
    }
    //创建Intent
    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;
    }

homeIntent.setComponent()设置需要启动的包名和HomeActivity信息homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK),分配新的任务栈。在getHomeIntent()中创建Intent,并将mTopAction和mTopdata作为参数传入Intent中,其中 mTopAction 默认为 Intent.ACTION_MAIN,同时设置Gategory为Intent.CATEGORY_HOME。系统通过Intent的参数匹配Launcher的AndroidManifest中的内容,启动Launcher进程。


系统启动流程

从Android系统按下电源键到Launcher进程的启动总结如下:


当Launcher进程启动完成,系统桌面展示出已经安装的应用程序图标。至此整个Android系统启动流程就结束了。

还不会的同学赶紧学起来吧,感谢您的阅读,创造不易,如果您觉得本篇文章对您有帮助,请点击关注小编,您的支持就是小编创作的最大动力!

后续文章逐渐深入WMS,PMS等Framework层,剖析源码,关注小编,学习不迷路!