深入理解Android內核——Android啓動分析

系統啓動進程

android設備的啓動分爲三個階段:Boot Loader, Linux Kernel,Android 系統服務。Android系統實際上是運行在Linux Kernel之上的一系列系統服務進程。init進程是Android中被啓動的第一個進程,PID = 0 。它通過解析init.rc腳本來構建出android運行初始化形態(android系統服務程序大多是在這個腳本中被啓動)
系統啓動流程圖可以從這個圖裏面看出,這個網上找的一張,這裏是出處
這裏寫圖片描述

init.rc初始化腳本

腳本包括actions、commands、services、options四種類型聲明。
actions實際上是響應某個觸發(也叫事件),當觸發(事件)發生時運行action,格式如下:

on <trigger>##觸發條件
    <command>##要執行的命令
    <command>##要執行的命令
    ...

常見觸發有下面幾種:

  • boot 。這是init程序啓動後觸發的第一個事件
  • device-added-< path>。當設備節點添加或者刪除時觸發事件
  • device-removed-< path>。
  • service-exited-< name>。當指定的name服務存在時觸發事件

services是可執行程序,形式如下

service <name><pathname>[<argument>]*
    <option>
    <option>
    ...

pathname表示service程序所在路徑,裏面有程序源碼。因爲是可執行程序,所有必須有路徑。
commandsoptions比較多,不一一介紹。

由於還沒有編譯源碼,所有在source中找不到代碼路徑:\system\core\init\init.c,此處盜用網上一般的init.c分析,下次找到了再自己具體分析。

int main(int argc, char **argv)
{
// 1、設置子進程退出的信號處理函數:sigchld_handler
...
// 2、創建文件夾,並掛載設備
mkdir("/dev", 0755);
mkdir("/proc", 0755);
....
// 3、重定向標準輸入輸出錯誤到 /dev/__null__
...
// 4、解析 init.rc 腳本
parse_config_file("/init.rc");
// 5、解析機器相關的配置文件,一般相關的放在init.rc中利用service action調過去
snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
parse_config_file(tmp);
// 6、建立 uevent,用於與linux kernel交互的socket
...
// 7、初始化及加載屬性相關資源
...
// 8、執行 on init 、early-boot 及 boot 片段動作,這些定義於 init.rc 中
/* execute all the boot actions to get us started */
action_for_each_trigger("init", action_add_queue_tail);
drain_action_queue();
/* execute all the boot actions to get us started */
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);

9.init進程的處理循環
for(;;) {
// I、執行init.rc 腳本中的動作
drain_action_queue();
// II、執行標誌爲SVC_RESTARTING的進程,利用fork+execve啓動新的進程
restart_processes();
...
}
return 0;
}

系統關鍵服務的啓動簡介

在上述init程序啓動中,通過解析init.rc,實際上也就陸續啓動了其他關鍵服務,這些服務中最重要的就是ServiceManager,Zygote,SystemServer三個系統服務進程。例如在啓動boot觸發事件中就有啓動Zygote服務。

ServiceManger–DNS服務器

ServiceManager簡稱SM,是Android Binder機制中的”DNS服務器”,負責域名(某個Binder服務在SM中註冊時提供的名字)到IP地址(由底層Binder驅動分配的值)的解析。SM在init.rc中的描述如下所示

service serviceManager /system/bin/servicemanager
    class core #同一個class名(此處爲core)的所有服務進程同時啓動/停止
    user system
    group system
    critical 
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm

/system/bin/servicemanager路徑表示該服務真正的執行程序在該路徑下。當SM每次重啓時,其他關鍵進程如zygote , media, surfaceflinger, drm也會重啓。

Zygote–受精卵孕育新線程/進程

Android中大多數應用進程和系統進程都是通過Zygote來生成的。zygote進程在內部會先啓動虛擬機,繼而加載一些必要的系統資源和系統類,最後進入一種監聽狀態。在後續的運作中,當其他系統模塊(比如AMS)希望創建新進程時,只需向zygote進程發出請求,zygote進程監聽到該請求後,會相應地“分裂”出新的進程,於是這個新進程在初生之時,就先天具有了自己的Dalvik虛擬機以及系統資源。出自這裏。Zygote在init.rc中的描述如下所示

service zygote /system/bin/app_process /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
    onreatart restart netd

在app_process程序中,最核心的代碼是下面這句

...
runtime.start("com.android.internal.os.zygoteInit",startSystemServer?"start-system -server":"");
...

runtime 運行時環境變量啓動了虛擬機,讓ZygoteInit在虛擬機上運行。Zygote.java文件提供幾個static方法在ZygoteInit.java等類中被使用。例如ZygoteInit中的startSystemServer方法調用了 Zygote.forkSystemServer()方法。(實際上startSystemServer方法也是ZygoteInit主要作用之一)。
ZygoteInit的作用:

  • 啓動SystemServer。該服務也是由Zygote fork而來。
  • 利用preload,預裝載各種系統類,main()方法如下所示
    static void main() {
        Log.d(TAG, "begin preload");
        registerZygoteSocket();
        preloadClasses();
        preloadResources();
        startSystemServer();
        runSelectLoop();
        closeServerSocket();
    }

SystemServer–Android的系統服務

SystemServer是Android進入Launcher之前的最後準備,它提供了衆多的java語言系統服務。由ZygoteInit中的startSystemServer經過層層調用(包括native code),最後到達SystemServer中的run()方法。在run()方法中:

...
 // Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//應該是添加的第一個LocalService,SSM本身也是服務
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
try{
     startBootstrapServices();
     startCoreServices();
     startOtherServices();
}

在startBootstarpServices()中啓動並註冊了下面幾種服務:

  • ActivityManagerService
  • PowerManagerService
  • DisplayManagerService
  • LightsService
  • PackageManagerService
  • UserManagerService
  • SensorService(native)

在startCoreServices()中啓動並註冊了下面幾種服務:

  • BatteryService
  • UsageStatsService
  • WebViewUpdateService

在startOtherServices()中啓動並註冊了下面幾種服務:

  • WindowManagerService
  • NetworkStatsService
  • InputManagerService
  • AudioService
  • CameraService

將java層的開機流程大致的畫在一張圖上,如下:
這裏寫圖片描述

對於zygote,作爲一個最原始的“受精卵”,它必須在合適的時機進行必要的細胞分裂。分裂動作也沒什麼大的花樣,不過就是fork()新進程而已。如果fork()出的新進程是system server,那麼其最終執行的就是SystemServer類的main()函數,而如果fork()出的新進程是普通的用戶進程的話,那麼其最終執行的就是ActivityThread類的main()函數。有關ActivityThread的細節,我們有時間再深入探討,這裏就不細說了。上述一段話引用自這裏

至此,android啓動差不多完成了,原來開機時系統竟然做了這麼多事情,66666。下章分析ActivityManagerService,AMS是導致Launcher被啓動的關鍵所在。

發佈了36 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章