Skip to content

Latest commit

 

History

History

ch10_android_bootup_progress

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Android 開機流程概觀

上一章:Android 的 Makefile -- Android.mk

本章節將介紹Android開機過程中所發生的事情。

首先要有一個認知,Android系統本身就帶有非常多的服務(system service),而這些服務大多運行在某個叫做xxx server的process內(如mediaserversystem_server,不過有一部份的名稱沒有server這個字眼)。這些服務有的是C++層提供有的是Java層提供。C++層提供的服務大多是一個服務一個process(如mediaserversurfaceflinger,而Java層則將所有Java層的服務都跑在system_server這個process裡了。

大體上來說,Android的開機過程如下:

  1. Linux Kernel 準備完成
  2. 執行init (第一個userspace程式,也是Android的第一行),過程中init會成為property service
  3. init過程中叫起大部份的C++層服務,並啟開機動畫。
  4. init最後執行app_process64,正式完成init的工作。
  5. app_process64會準備好一台JVM,並用JVM載入com.android.internal.os.ZygoteInit這個class(以下簡稱zygote)。(ZygoteInit是java的第一行,執行的是main())
  6. zygote會在過程中啟動SystemServer,內含Java層的系統服務。
  7. 系統準備好後結束開機動畫,啟動launcherzygote會留下來負責產生的Android App。

Linux Kernel

// TODO

init

init是Linux系統執行的第一行usersapce程式,而Android使用自製的init。Android的init會讀取init.rc檔案來執行動作,所以我們不用真的修改它的原始碼便能為你的系統增加一些功能。

init在執行過程中會變成property service來處理Android系統中的屬性。我們可以在adb shell內用getpropsetprop工具來取得/修改系統中的property資訊。

initinit.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/*

app_process64

非常小的一支程式,會啟動一台JVM(用一個叫AppRuntime的class封裝),並且用這台JVM載入com.android.internal.os.ZygoteInit這個class。接著ZygoteInit內的main(String[] argv)就會被執行。

AppRuntime繼承了AndroidRuntime,這個class主要處理從C++到Java的JNI流程。大致上是:

  1. 用C++產生一台JVM
  2. 設定好JVM
  3. 告訴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

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_servermain(),程式碼會是$TOP/frameworks/base/services/java/com/android/server/SystemServer.java

參考檔案

  • $TOP/frameworks/base/services/java/com/android/server/SystemServer.java

SystemServer

在SystemServer開始執行後,他會先準備好需要用到的jni library(叫做libandroid_servers),並開始將Java層的系統服務準備好。 接下來會建立一個系統用的Context(createSystemContext(),產生一個新的SystemServiceManager(mSystemServiceManager = new SystemServiceManager(mSystemContext);),然後在LocalServices內加入SystemServiceManager

接著依序執行startBootstrapServices()startCoreServices()startOtherServices(),完成後進入Looper.loop()狀態,等待其它程式送指令交待給它。

完成!

到此我們對Android的啟動流程就有初步的認識了!