上一章:Android 的 Makefile
-- Android.mk
本章節將介紹Android開機過程中所發生的事情。
首先要有一個認知,Android系統本身就帶有非常多的服務(system service),而這些服務大多運行在某個叫做xxx server的process內(如mediaserver
,system_server
,不過有一部份的名稱沒有server這個字眼)。這些服務有的是C++層提供有的是Java層提供。C++層提供的服務大多是一個服務一個process(如mediaserver
,surfaceflinger
,而Java層則將所有Java層的服務都跑在system_server
這個process裡了。
大體上來說,Android的開機過程如下:
Linux Kernel
準備完成- 執行
init
(第一個userspace程式,也是Android的第一行),過程中init會成為property service
。 init
過程中叫起大部份的C++層服務,並啟開機動畫。init
最後執行app_process64
,正式完成init
的工作。app_process64
會準備好一台JVM
,並用JVM
載入com.android.internal.os.ZygoteInit
這個class(以下簡稱zygote
)。(ZygoteInit
是java的第一行,執行的是main()
)zygote
會在過程中啟動SystemServer
,內含Java層的系統服務。- 系統準備好後結束開機動畫,啟動
launcher
。zygote
會留下來負責產生的Android App。
// TODO
init
是Linux系統執行的第一行usersapce程式,而Android使用自製的init。Android的init會讀取init.rc
檔案來執行動作,所以我們不用真的修改它的原始碼便能為你的系統增加一些功能。
init
在執行過程中會變成property service
來處理Android系統中的屬性。我們可以在adb shell
內用getprop
和setprop
工具來取得/修改系統中的property資訊。
init
為init.rc
量身訂製了一套Android Init Language
,用來充當init
的設定檔。Andorid Init Language
中也有service
一詞,記得別和Android App的Service搞混嘍!
另外要注意的是,有些*.rc
的檔案不會放在$TOP/system/core/rootdir/
內,而是改採放在自己專案下並在Android.mk
中宣告LOCAL_INIT_RC := xxx.rc
的方式。比如說如mediaserver
就是放在$TOP/framework/av/media/mediaserver/mediaserver.rc
// TODO
$TOP/system/core/init/*
$TOP/system/core/rootdir/*
非常小的一支程式,會啟動一台JVM
(用一個叫AppRuntime
的class封裝),並且用這台JVM
載入com.android.internal.os.ZygoteInit
這個class。接著ZygoteInit
內的main(String[] argv)
就會被執行。
AppRuntime
繼承了AndroidRuntime
,這個class主要處理從C++到Java的JNI流程。大致上是:
- 用C++產生一台
JVM
- 設定好
JVM
- 告訴
JVM
要執行的main(String[] argv)
是哪個。
$TOP/framework/base/cmds/app_process
$TOP/framework/base/include/android_runtime/AndroidRuntime.h
$TOP/framework/base/core/jni/AndroidRuntime.cpp
$TOP/framework/base/core/java/com/android/internal/os/ZygoteInit.java
ZygoteInit
會註冊一個socket,之後會用來接收別人要它產生新app的需求。在開機流程中執行的ZygoteInit
會帶start-system-server
這個參數,而收到這個參數時ZygoteInit
會自我fork來產生Java層的系統服務(system_server
)。
在自我fork的過程中,會利用ZygoteConnection
來產生參數,最終則執行Zygote.forkSystemServer(...)
,從此這個process就fork成了parent(Zygote.forkSystemServer()
回傳child的id)及child(Zygote.forkSystemServer()
回傳的id為0)。其中child prcess會變成system_server
,而原本的ZygoteInit
則會繼續它自己的使命--接收參數並產生新的process(包括app的process)。
child process首先會關掉zygote socket,接著開始準備自己。會先產生一個西為class loader
的Java類別,並在裡面設定好service.jar
的位置(一般來說會是/system/framework/services.jar
),然後執行RuntimeInit.zygoteInit(...)
。RuntimeInit.zygoteInit
會再調用RuntimeInit.applicationInit(...)
並最終執行class loader
中class的main()
--也就是system_server
的main()
,程式碼會是$TOP/frameworks/base/services/java/com/android/server/SystemServer.java
。
$TOP/frameworks/base/services/java/com/android/server/SystemServer.java
在SystemServer開始執行後,他會先準備好需要用到的jni library(叫做libandroid_servers
),並開始將Java層的系統服務準備好。
接下來會建立一個系統用的Context
(createSystemContext()
,產生一個新的SystemServiceManager
(mSystemServiceManager = new SystemServiceManager(mSystemContext);
),然後在LocalServices內加入SystemServiceManager
。
接著依序執行startBootstrapServices()
、startCoreServices()
、startOtherServices()
,完成後進入Looper.loop()
狀態,等待其它程式送指令交待給它。
到此我們對Android的啟動流程就有初步的認識了!