遙想當年,剛接觸android那會,心裏一直很想弄明白,Android的開機流程到底是怎樣的?但當時一來剛入這行,什麼也不懂,有點無從下手,二來忙着完成手頭工做,也沒時間。如今恰好有點時間,也來簡單捋捋Android系統開機的過程當中,都發生了什麼。本篇文章儘可能不涉及代碼,只講流程。java
看過我上一篇文章《Android系統框架》的人應該還有印象(沒看過的待會能夠在文末點開連接前往看看),Android系統由上至下大體可分爲五層,分別是Applications層,Framework層,Native層,Hardware層,Kernel層。顯然,在這五層中,Android設備最早進入的就是Kernel層。那麼咱們就先從這一層入手,Android是如何進入這一層的。android
所謂Kernel層,其實就是系統跑到了Linux內核,而在系統進入Linux內核以前,其實還經歷了一個階段,那就是bootloader。而在Android系統中,uboot就是一種常見的bootloader程序。這裏會以MTK平臺做爲例子,來簡單介紹從機器上電到進入kernel層發生的事。須要事先說明的是,MTK平臺會比其它平臺多出一個preloader階段,這個下面會說到。服務器
preloader按照mtk的說法是MTK in-house developed loader,也就說是mtk內部開發的一個loader。微信
首先須要明確的是preloader、lk、kernel、android這些系統鏡像文件是存儲在flash中的,而不是在CPU芯片或者DDR中。app
而後每一個mtk芯片都有個boot rom(能夠當作是一段指令),在上電時刻,boot rom開始啓動,boot rom加載preloader到內部的SRAM中,爲何是加載到內部的SRAM中,而不是外部RAM中呢,是由於這個時候外部RAM尚未被初始化好,preloader被加載完成以後,程序就從boot rom跳轉到preloader處開始執行,preloader初始化好外部RAM以後,preloader將lk(或uboot)加載外部RAM中,而後跳轉到lk(或uboot)中去執行,lk(或uboot)緊接着就加載bootimage(包括kernel和ramdisk)到外部RAM中,而後去執行kernel部分。啓動過程如圖所示:框架
簡單總結以下:socket
系統上電->Rom boot->Pre-loader->lk(u-boot)->kernel
複製代碼
從上電到系統進入到內核階段,這就是系統大概作的事情。接下來要說的是Linux內核的「天字一號」進程,init。函數
init進程其實也是Android系統的第一個進程,由於Android就是基於Linux內核的。init的進程號是1,這是一個極其重要的進程,身負重任。java世界的開創者Zygote就是它建立的。源碼分析
那zygote進程是怎麼被建立出來,從而建立出整個java世界呢?post
先大概列出init進程的工做流程:
1.解析init.rc文件;
2.執行init.rc文件中各個階段的動做,而建立zygote的工做就是其中的某個階段完成的;
3.調用property_init初始化屬性相關的資源,而且經過property_start_service啓動屬性服務;
4.init進入一個無限循環,而且等待一些事情的發生。
複製代碼
在這裏,咱們只關心第二個階段,即zygote的建立。既然zygote是經過解析init.rc文件建立,那咱們先看看這個init.rc文件:
//init.rc
import /init.${ro.zygote}.rc
複製代碼
從上面的語句能夠看到,init.rc並非直接引入某個固定的文件,而是根據屬性ro.zygote的內容來引入不一樣的文件。
屬性ro.zygote的值有四種狀況:
zygote32:純32位模式
zygote32_64:混32位模式(即32位爲主,64位爲輔)模式
zygote64:純64位模式
zygote64_32:混64位模式(即 64位爲主,32位爲輔)模式
複製代碼
這裏以zygote32爲例,咱們看看zygote32.rc文件:
//zygote32.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
writepid /dev/cpuset/foreground/tasks
複製代碼
這裏經過start service的方式啓動zygote,會fork出一個進程,這個進程就是zygote。 zygote建立後,會執行以下bin文件:
/system/bin/app_process
複製代碼
app_process對應的源文件是App_main.cpp,這裏不貼源碼,只是作大概介紹。App_main.cpp路徑以下:
/frameworks/base/cmds/app_process/app_main.cpp
複製代碼
而在app_process中主要作的一件事就是調用AppRuntime的start方法。AppRuntime由AndroidRuntime類派生出來,而在AndroidRuntime的start方法中主要作了三件事:
/frameworks/base/core/jni/AndroidRuntime.cpp
1.建立虛擬機---startVm;
2.註冊JNI函數---startReg;
3.經過JNI調用Java函數,調用的函數是ZygoteInit的main函數。
複製代碼
這是開創android系統的Java世界的三大步,在這以後,zygote就正式進入了Java世界,繁殖framework的核心system_server進程。接着等待請求,孵化app,建立一個又一個的子子孫孫。launcher就是zygote的後代。
Android系統從上電,前後通過了以下流程:
系統上電->Rom boot->Pre-loader->lk(u-boot)->kernel->init->zygote->system_server&app
複製代碼
若是從開機界面上來作區分的話,上電開機的時候,顯示的開機logo,第一個階段是uboot,第二階段是kernel階段,若是你看到開機logo一直沒變,那是由於這兩個階段用的logo是同一張。第三階段則是開機動畫,這時已經進入Java的世界,等待launcher加載完成,就能夠結束開機動畫,從而進入咱們熟悉的launcher界面。
這裏簡單梳理了下Android上電後發生的一些事情,徹底沒涉及到源碼分析,也只是簡單粗略大概講了下流程。不少沒有涉及,如uboot階段的一些硬件參數初始化,如init在起來的時候不止啓動了zygote,還建立了不少守護進程,也建立了Android系統的屬性服務器,如zygote孵化出來的system_server所作的事,它會啓動Android系統的核心服務。。。
Android系統很龐大,咱們的全部的瞭解都只是冰山一角。希望這篇文件可以給你帶來一絲絲的對android系統開機流程的瞭解。
若是文章存在錯誤描述,可直接留言,一塊兒探討!
我在微信公衆號也有寫文章,更新比較及時,有興趣者能夠關注以下公衆號!