Android N 開機啓動流程概述

前言

做android開發已經好些年頭,一直對android系統的開機啓動流程一知半解。前前後後看了不少文章和源碼,在這裏把自己的一些總結記錄下來,也算是加深自己的理解。

Android N 開機啓動流程概述

相信只要接觸過Android的人,都會看過下面這張圖: 


Android層次架構圖

 

圖片展示了Android的五層架構,從上到下依次是:應用層,應用框架層,庫層,運行時層以及Linux內核層。而Android的啓動流程是自下而上的,大體上分爲三個階段:1. BootLoader引導;2. 啓動Kernel;3. 啓動Android。如果再細化一點,則如下圖所示:

 


這裏寫圖片描述

Android的啓動流程圖

 

 Android的啓動過程可以分爲兩個階段,第一階段是Linux的啓動,第二階段纔是Android的啓動。上圖中1、2、3是linux啓動的過程,從4開始就是android啓動的過程。 
 下面我詳細描述一下過程:

Step 1. Boot Rom 
 當按開機鍵的時候,引導芯片開始從固化在ROM的預設代碼開始執行,然後加載引導程序到RAM。

Step 2. Bootloader 
 BootLoader,又稱爲引導程序。它是在操作系統運行之前運行的一段程序,是運行的第一個程序。主要有檢查RAM,初始化硬件參數等功能,當然它的最終目的是把操作系統給拉起來。

 文件路徑/bootable/bootloader/legacy/

 BootLoader的主要功能分析,我摘抄過來,一起看看:

其實Bootloader主要的必須的作用只有一個:就是把操作系統映像文件拷貝到RAM中去,然後跳轉到它的入口處去執行,我們稱之爲啓動加載模式,該過程沒有用戶的介入,是它正常工作的模式。它的步驟如下:

Stage1:

硬件設備初始化。爲stage2的執行及隨後內核的執行準備好基本的硬件環境

爲加載stage2 準備ram空間。爲了獲得更好的執行速度,通常吧stage2加載到ram中執行

複製stage2的代碼到ram中

設置好堆棧

跳轉到stage2的c程序入口
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Stage2:

初始化本階段要使用的硬件設備

檢測系統內存映射

將內核映像和根文件系統映像從flash讀到ram中

爲內核設置啓動參數

調用內核
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

(摘自:http://www.cnblogs.com/little221/archive/2012/12/06/2804387.html

 簡單的說,Bootloader負責初始化軟件運行所需要的最小硬件環境,最後加載內核到內存。

Step 3. 初始化Kernel 
 接着就進入C語言編寫的結構無關的代碼了。這個入口的函數是start_kernel函數。start_kernel 函數完成了內核的大部分初始化工作。實際上,可以將start_kernel 函數看做內核的main函數。start_kernel函數執行到最後調用了reset_init函數進行後續的初始化。 reset_init函數最主要的任務就是啓動內核線程kernel_init。kernel_init函數將完成設備驅動程序的初始化,並調用init_post函數啓動用戶空間的init進程。到init_post函數爲止,內核的初始化已經基本完成。

文件路徑:/kernel_imx/init/main.c

簡單的說,內核加載進內存後,將首先進入內核引導階段,在內核引導階段的最後,調用start_kernel進入內核啓動階段,主要是完成內核的大部分初始化工作。start_kernel會最終啓動用戶空間的init進程。

Step 4. init進程 
 當初始化內核之後,就會啓動一個相當重要的祖先進程,也就是init進程,在Linux中所有的進程都是由init進程直接或間接fork出來的。init進程負責創建系統中最關鍵的幾個核心daemon(守護)進程,尤其是zygote和servicemanager。前者是android啓動的第一個dalvik 虛擬機,它將負責啓動Java世界的進程;後者是BInder通信的基礎。另外,它還提供了property service(屬性服務),類似於windows系統的註冊表服務。

 在Android系統中,會有個init.rc腳本。init進程一啓動就會讀取並解析這個腳本文件,把其中的元素整理成自己的數據結構(鏈表)。

 換句話說, init進程負責解析init.rc配置文件,開啓系統守護進程。兩個最重要的守護進程是zygote進程和servicemanager,zygote是Android啓動的第一個Dalvik虛擬機,servicemanager是Binder通訊的基礎。

文件路徑: /system/core/init/init.c 
/system/core/rootdir/init.rc 
/system/core/init/readme.txt

Step 5. Zygote進程 
 當init進程創建之後,會fork出一個Zygote進程,這個進程是所有Java進程的父進程。我們知道,Linux是基於C的,而Android是基於Java的(當然底層也是C)。所以這裏就會fork出一個Zygote Java進程用來fork出其他的進程。在zygote開啓的時候,會調用ZygoteInit.main()進行初始化。下面我們看一段ZygoteInit.main()源碼:

    public static void main(String argv[]) {
        // Mark zygote start. This ensures that thread creation will throw
        // an error.
        ZygoteHooks.startZygoteNoThreadCreation();

        try {
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
            RuntimeInit.enableDdms();
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();
// 加載zygote的時候,會傳入參數,startSystemServer變爲true
            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = 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.");
            }

            registerZygoteSocket(socketName);
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());
            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

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

            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

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

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

            ZygoteHooks.stopZygoteNoThreadCreation();
// 啓動SystemServer進程
            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

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

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

文件路徑:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

從代碼中可以看出,zygote虛擬機啓動子進程system_server,同時也可以看出zygote中定義了一個Socket,用於接收ActivityManagerService啓動應用程序的請求。

Step 6. SystemServer進程 
 前面ZygoteInit.java裏面通過startSystemServer() fork出了SystemServer進程,這個進程在整個的Android中非常重要,它和Zygote進程一樣,是Android Framework層的兩大重要進程。系統裏面重要的服務都是在這個進程裏面開啓的,例如AMS, WindowsManager, PackageManagerService等等都是由這個SystemServer fork出來的。在下面SystemServer 的代碼中可以看到,這些服務如何開啓和具體開啓了哪些服務。

文件路徑:/frameworks/base/services/java/com/android/server/SystemServer.java

 從SystemServer.java文件代碼中可以看出,在SystemServer進程開啓的時候,就會初始化ActivityManagerService 。同時,會加載本地系統的服務庫,調用createSystemContext()創建系統上下文,創建ActivityThread及開啓各種服務等等。 
 也就是說在system_server中開啓了核心系統服務,並將系統服務添加到ServiceManager中,然後系統進入SystemReady狀態。

Step 7. Home Activity

 上面ActivityManagerService 開啓之後,會調用finishBooting() ,完成引導過程,同時發送開機廣播。

文件路徑:/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

 之後就會啓動Home程序,完成系統界面的加載與顯示。

其實這一步遠比上面所說的複雜,具體步驟是:

1、在systemReady狀態,ActivityManagerService會與zygote的Socket通信,請求啓動Home。 
2、zygote收到AMS的連接請求後,執行runSelectLoopMode處理請求。 
3、zygote處理請求會通過forkAndSpecialize啓動新的應用進程,並最終啓動Home。

Android的開機啓動流程就完成了。

總結一下整個開機啓動流程:

Step1 系統加電,執行bootloader。Bootloader負責初始化軟件運行所需要的最小硬件環境,最後加載內核到內存。 
Step2 內核加載進內存後,將首先進入內核引導階段,在內核引導階段的最後,調用start_kernel進入內核啓動階段。start_kernel最終啓動用戶空間的init程序。 
Step3 init程序負責解析init.rc配置文件,開啓系統守護進程。兩個最重要的守護進程是zygote進程和ServiceManager,zygote是Android啓動的第一個Dalvik虛擬機,ServiceManager是Binder通訊的基礎。 
Step4 zygote虛擬機啓動子進程system_server,在system_server中開啓了核心系統服務,並將系統服務添加到ServiceManager中,然後系統進入SystemReady狀態。 
Step5 在SystemReady狀態,ActivityManagerService與zygote中的socket通信,通過zygote啓動home應用,進入系統桌面。

從Step3開始,init啓動後,上層的實現。

Step1 init啓動的核心Daemon服務包括Android的第一個Dalvik虛擬機zygote。 
Step2 zygote定義一個socket,用於接受ActivityManagerService啓動應用的請求。 
Step3 zygote通過fork系統調用創建system_server進程 
Step4 在system_server進程中,將會啓動系統核心服務以及其他服務。 
Step5 系統服務啓動後會註冊到ServiceManager中,用於Binder通信。 
Step6 ActivityManagerService進入systemReady狀態。 
Step7 在systemReady狀態,ActivityManagerService會與zygote的Socket通信,請求啓動Home。 
Step8 zygote收到AMS的連接請求後,執行runSelectLoopMode處理請求。 
Step9 zygote處理請求會通過forkAndSpecialize啓動新的應用進程,並最終啓動Home。

參考文檔:http://blog.csdn.net/frakie_kwok/article/details/70196986 
http://www.jianshu.com/p/45cf56172d22 
http://blog.csdn.net/dd864140130/article/details/57624948

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章