Android的開機啟動流程


1、Android的開機啟動流程

Android的層次框架圖,如下所示:

圖片清晰地展示了Android的五層架構,從上到下依次是:應用層、應用框架層、庫層、運行時層以及Linux內核層。Android的啟動流程是自下向上的,大體上可以分為三個階段:1、BootLoader引導啟動內核;2、啟動Linux內核;3、啟動Android系統。

Android的啟動流程如下所示:

接下來具體地描述一下啟動過程:

Step 1. Boot Rom

當長按電源開機的時候,引導芯片開始從固化在ROM的預設代碼開始執行,然后將加載引導程序到RAM中。

 

Step 2. BootLoader

BootLoader又稱為引導程序,它在運行操作系統之前運行的一段程序,是運行的第一個程序。主要的功能有檢查RAM、初始化一些硬件外設等功能,它最終的目的是啟動操作系統。

文件的路徑為:

/bootable/bootloader/

BootLoader的最主要功能是將操作系統進行啟動,把操作系統的鏡像文件拷貝到RAM中去,然后跳轉到它的入口處去執行,我們稱之為啟動加載模式,該過程沒有用戶的介入,是它正常的工作模式,其步驟如下:

Stage 1:

(1)硬件初始化,為Stage 2的執行以及隨后內核的運行准備好基本的硬件環境;

(2)為加載Stage 2准備RAM空間,為了獲得更好的執行速度,通常把Stage 2加載到RAM中執行;

(3)復制Stage 2的代碼到RAM中;

(4)設置好堆棧;

(5)跳轉到Stage 2的C程序入口。

Stage 2:

(1)初始化本階段要使用的硬件設備;

(2)檢測系統內存映射;

(3)將內核鏡像和根文件系統從ROM讀到RAM中;

(4)為內核設置好啟動參數;

(5)啟動內核。

 

Step 3. 初始化Kernel

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

文件路徑:

/kernel/init/main.c

 

Step 4. init進程

當初始化內核之后,就會啟動一個相當重要的祖先進程,也就是init進程,在Linux系統中,所有的進程都是由init進程直接或間接fork出來的。init進程負責創建系統中最關鍵的幾個子進程,尤其是Zygote進程,另外,它還提供了property service,類似於Windows系統的注冊表服務。

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

文件路徑:

/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[]) {

......

    // 加載zygote的時候,會傳入參數,startSystemServer變為true
     boolean startSystemServer = false;
     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]);
                }
            }

......

         // 啟動的SystemServer進程
     if (startSystemServer) {
                startSystemServer(abiList, socketName);
         }
......
}

源碼的文件路徑:

/framework/base/core/java/com/android/internal/os/ZygoteInit.java

 

Step 6. SystemServer進程

前面的ZygoteInit.java文件中,通過startSystemServer()函數fork出了SystemServer進程,這個進程在整個Android系統中非常重要,它和Zygote進程一樣,是Android Framework層的兩大重要進程。系統里面的服務都是在這個進程里面開啟的,例如AWS、WindowsManager等都是由這個SystemServer進程fork出來的。

在下面的代碼中,可以看到服務如何開啟並具體開啟了哪些服務:

public final class SystemServer {


    // The main entry point from zygote.
    public static void main(String[] args) {
        new SystemServer().run();
    }

    public SystemServer() {
        // Check for factory test mode.
        mFactoryTestMode = FactoryTest.getMode();
    }

    private void run() {

......

        // 初始化原生服務庫
        System.loadLibrary("android_servers");
        nativeInit();

        // 初始化系統上下文
        createSystemContext();

        // 創建SystemServiceManager對象
        mSystemServiceManager = new SystemServiceManager(mSystemContext);

        // 開啟服務
        try {
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        }
        
        ......

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

    //初始化系統上下文對象mSystemContext,並設置默認的主題。
    private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
    }

    //在這里開啟了幾個核心的服務,因為這些服務之間相互依賴,所以都放在了這個方法里面。
    private void startBootstrapServices() {
    
......
    
        //初始化ActivityManagerService
        mActivityManagerService = mSystemServiceManager
              .startService(ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

        //初始化PowerManagerService,因為其他服務需要依賴這個Service,因此需要盡快的初始化
        mPowerManagerService = mSystemServiceManager
              .startService(PowerManagerService.class);

        // 現在電源管理已經開啟,ActivityManagerService負責電源管理功能
        mActivityManagerService.initPowerManagement();

        // 開啟DisplayManagerService
        mDisplayManagerService = mSystemServiceManager
              .startService(DisplayManagerService.class);

        // 開啟PackageManagerService
        mPackageManagerService = PackageManagerService.main(mSystemContext,mInstaller,
              mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

......
    }

    private void startCoreServices() {...}// 啟動一些基本服務。
    
    private void startOtherServices() {...}// 啟動其他服務。
}

源文件文件路徑:

/framework/base/core/java/com/android/server/SystemServer.java

 

Step 7. Home Activity

 在上面的ActivityManagerService開啟之后,會調用finishBooting()函數,完成引導過程,同時發送開機廣播"ACTION_BOOT_COMPLETED"。

下面是finishBooting()源碼:

final void finishBooting() {

......
    final int userId = mStartedUsers.keyAt(i);
    Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
    intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
    broadcastIntentLocked(...);
......

}

文件路徑:

/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

之后就會開啟系統的主程序-Launcher程序,完成系統界面的加載與顯示。

 

文章轉載之:

https://www.jianshu.com/p/45cf56172d22

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM