天天看點

Android系統啟動流程完整分析(一)

接觸Android也有幾年了,最近想對Android系統的啟動流程做一個完整的分析總結,以便後續學習 。

(1)Android架構介紹

我們先來看一下Android文檔給的一份系統架構圖。

Android系統啟動流程完整分析(一)

從以上可以看到,Android大體上被分為4個子產品(Kernel,Hal/Native,Java Framework,Apps)。

接下來我們從系統啟動的角度來看兩種更加詳細的圖。

Android系統啟動流程完整分析(一)
Android系統啟動流程完整分析(一)

從上圖可以看出,系統啟動我們底層将其主要分為三個部分。

  • Android裝置上電後,首先會從處理器片上ROM的啟動引導代碼開始執行,片上ROM會尋找Bootloader代碼,并加載到記憶體。
  • Bootloader開始執行,首先負責完成硬體的初始化,然後找到Linux核心代碼,并加載到記憶體。
  • Linux核心開始啟動,初始化各種軟硬體環境,加載驅動程式,挂載根檔案系統,并執行init程式,由此開啟Android的世界。

每一層的作用不做介紹,這裡主要講涉及的鏡像有boot.img、system.img、vendor.img、recovery.img、userdata.img、cache.img,與平台相關的鏡像有lk.bin(MTK)、preloader.img(MTK)、logo.bin(MTK)等,通常來說,修改kernel層通常編譯boot.img即可,修改Framework層或Native層主要是編譯system.img。

(2)Android啟動概述

概述:Loader > Kernel > Native > Framework > Application

細分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher

  • Loader層主要包括Boot Rom和Boot Loader
  • Kernel層主要是Android核心層
  • Native層主要是包括init程序以及其fork出來的使用者空間的守護程序、HAL層、開機動畫等
  • Framework層主要是AMS和PMS等Service的初始化
  • Application層主要指SystemUI、Launcher的啟動

kernel的C啟動階段可以了解為真正的啟動階段,Linux下有3個特殊的程序,idle(swapper)程序(PID = 0)、init程序(PID = 1)和kthreadd(PID = 2)。

  • idle(swapper)程序由系統自動建立,運作在核心态

    idle程序其pid=0,其前身是系統建立的第一個程序,也是唯一一個沒有通過fork或者kernel_thread産生的程序。

    完成加載系統後,演變為程序排程、交換,常常被稱為交換程序。

  • init程序由idle通過kernel_thread建立,在核心空間完成初始化後,加載init程式,并最終轉變為使用者空間的init程序

    由0程序建立,完成系統的初始化,是系統中所有其它使用者程序的祖先程序。

    Linux中的所有程序都是有init程序建立并運作的。首先Linux核心啟動,然後在使用者空間中啟動init程序,再啟動其他系統程序。

    在系統啟動完成後,init将變為守護程序監視系統其他程序。

  • kthreadd程序由idle通過kernel_thread建立,并始終運作在核心空間,負責所有核心線程的排程和管理

    它的任務就是管理和排程其他核心線程kernel_thread,會循環執行一個kthreadd的函數,該函數的作用就是運作kthread_create_list全局連結清單中維護的kthread,當我們調用kernel_thread建立的核心線程會被加入到此連結清單中,是以所有的核心線程都是直接或者間接的以kthreadd為父程序。

以上程序可以通過如下圖檔展示:

Android系統啟動流程完整分析(一)

可通過ps -A(查詢程序)和ps -T -p xxx(查詢xxx程序中的線程數)指令來檢視Android系統相關程序。

//ps -A
USER           PID  PPID     VSZ    RSS WCHAN            ADDR S NAME                       
root             1     0   68444   3052 0                   0 S init
root             2     0       0      0 0                   0 S [kthreadd]

root             3     2       0      0 0                   0 I [rcu_gp]
root             4     2       0      0 0                   0 I [kworker/0:0]
root             5     2       0      0 0                   0 I [kworker/0:0H]
root            13     2       0      0 0                   0 S [watchdog/0]
root            14     2       0      0 0                   0 S [cpuhp/0]
root            15     2       0      0 0                   0 S [cpuhp/1]
...

root           459     1   34620    872 0                   0 S init
root           461     1   36156   3544 0                   0 S ueventd
system         478     1   29772   1532 0                   0 S servicemanager
system         479     1 2132152   3036 0                   0 S hwservicemanager
root           609     1 2487788   5064 0                   0 S netd
root           610     1 5495940  86496 0                   0 S zygote64
root           611     1 1813256  69932 0                   0 S zygote
root           626     1   30980   2292 0                   0 S healthd
audioserver    685     1 2396272   8056 0                   0 S audioserver
system         686     1   86580   2332 0                   0 S displayservice
system         691     1 3022164  23440 0                   0 S surfaceflinger
cameraserver   782     1   43032   4820 0                   0 S cameraserver
media          805     1  183008   5824 0                   0 S mediaserver
system        1268   775 10563968 372340 0                  0 S system_server
shell         7278     1  108560   3672 0                   0 S adbd
shell         7279     1   77376    776 0                   0 S hdbd
           
root           610     1 5495940  86496 0                   0 S zygote64
system        1695   610 6086164 108188 0                   0 S com.android.settings
u0_a26        1719   610 7740036 246752 0                   0 S com.android.systemui
radio         2138   610 6634868 104272 0                   0 S com.android.phone
u0_a22        3363   610 6435100 121448 0                   0 S com.android.gallery3d
nfc           3447   610 5734092  61980 0                   0 S com.android.nfc
u0_a11        4170   610 5711704  68868 0                   0 S android.process.media
u0_a18        4303   610 6470168 140176 0                   0 S com.google.android.gms
...
           
//ps -T -p xxx
USER           PID   TID  PPID     VSZ    RSS WCHAN            ADDR S CMD            
system        1268  1268   610 10943004 318288 0                  0 S system_server
system        1268  1342   610 10943004 318288 0                  0 S android.display
system        1268  1343   610 10943004 318288 0                  0 S android.anim
system        1268  1347   610 10943004 318288 0                  0 S watchdog
system        1268  1364   610 10943004 318288 0                  0 S ActivityManagerService
system        1268  1412   610 10943004 318288 0                  0 S PowerManagerService
system        1268  1427   610 10943004 318288 0                  0 S PackageManagerService
system        1268  1517   610 10943004 318288 0                  0 S SensorService
system        1268  1535   610 10943004 318288 0                  0 S AlarmManager
system        1268  1571   610 10943004 318288 0                  0 S WifiService
system        1268  2212   610 10943004 318288 0                  0 S SoundPool
...
           

當 Linux 核心啟動後會初始化各種軟硬體環境,加載驅動程式,挂載根檔案系統,Linux 核心加載的最後階段會啟動執行第一個使用者空間程序 init 程序。

繼續閱讀