1. 程式人生 > >Android安全/開發基礎--9--Android系統的啟動過程分析

Android安全/開發基礎--9--Android系統的啟動過程分析

=================================================================

整個Android系統的啟動分為Linux核心的啟動和Android系統的啟動。

在這裡插入圖片描述

Android系統的啟動流程圖中部分名詞簡介:

Boot loader:載入程式。是在作業系統核心執行之前執行的一段小程式。它可以初始化硬體裝置、建立記憶體空間的對映圖,為最終呼叫作業系統核心準備好正確的環境。 HomeScreen:Android系統主螢幕/待機介面。

9-1、載入程式

加電後,CPU先執行bootloader載入程式,正常啟動系統,載入boot.img到RAM,然後執行,boot.img中包含核心。

載入程式分兩個階段執行。第一個階段,檢測外部的RAM以及載入對第二階段有用的程式,第二階段,載入程式設定網路、記憶體等等。

Android載入程式目錄(舊系統版本):\bootable\bootloader\legacy\usbloader

9-2、Linux核心

由bootloader載入kernel,kernel經自解壓、初始化、載入built-in驅動程式,完成啟動。Kernel啟動後會建立若干核心執行緒(kernel thread),之後裝入並執行程式/sbin/init/,載入init process,切換至user-space。

9-3、init程序

Init程序是一個由核心啟動的使用者級程序,它的程序號是1。核心自行啟動(已經被載入記憶體,開始執行,並已初始化所有的裝置驅動程式和資料結構等)之後,就通過啟動一個使用者級程式init的方式,完成引導程序。init始終是第一個程序,可以稱它為root程序或者所有程序的父程序。

相關目錄:

init程序目錄:/system/core/init/*
init.rc檔案目錄:/system/core/rootdir/init.rc
readme.txt目錄:/system/core/init/readme.txt

init程序的職責:

1、掛載目錄,比如/sys、/dev、 /proc
2、初始化屬性,提供property service(屬性服務)管理Android系統中的屬性
3、處理配置檔案命令(主要是init.rc指令碼檔案)
4、效能分析和執行其它程序

init程序的入口在system/core/init/init.cpp中,主要做了這些工作:

1、啟動準備:該階段包括建立檔案系統的基本目錄、開啟基本輸入、輸出裝置,初始化日誌功能等。 2、解析init.rc檔案:

該階段對init.rc指令碼檔案進行解析,主要對service和action進行解析並放入到對應的service/action_list列表中,其中Service由命令(command)和一系列服務的附加內容(option)選項組成, Action則由一系列的命令組成。 3、觸發需要執行的action:Action需要在Triggers(觸發條件)中呼叫,本階段對需要執行的Action進行觸發,並根據觸發條件將需要執行的Action放入Action佇列。 4、執行在action佇列中的命令:對上一階段觸發的Action及Service進行執行,並在此過程中,派生了Zygote和ServiceManager兩個非常重要的程序 5、迴圈處理事件:init程序進入無限迴圈,處理裝置插入/拔出,服務屬性狀態變化和signal事件等。

對於init.rc檔案,是Android自己規定的初始化指令碼(Android Init Language, system/core/init/readme.txt),它有特定的格式以及規則。也叫做Android初始化語言。

Android初始化語言由四大型別的宣告組成,即Actions(動作)、Commands(命令)、Services(服務)、以及Options(選項)。

Action(動作):動作是以命令流程命名的,有一個觸發器決定動作是否發生。 Service(服務):服務是init程序啟動的程式、當服務退出時init程序會視情況重啟服務。 Options(選項):選項是對服務的描述。它們影響init程序如何以及何時啟動服務。

9-4、Services

service:用於通知init程序建立一個名為Zygote的程序,這個Zygote程序要執行的程式是/system/bin/app_process,後面是要傳給app_process的引數。

在init程序中,可以使用如下方式啟動Service:

1、在action下面新增和啟動服務相關的command。 2、使用函式restart_processes()和restart_service_if_needed()重啟Service,該函式位於init的主執行緒迴圈中,功能是檢視是否有需要重新啟動的service。 3、在檔案/system/core/init/property_service.c中,使用函式handle_property_set_f()向Socket中名稱為property_service的屬性服務傳送控制的資訊,這樣就可以進入到該函式中。 4、使用函式handle_keychord()啟動,該函式和chorded keyboard有關,功能是處理註冊在Service structure上的keychord,通常是啟動Service。

9-5、Zygote/Dalvik/ART

1、Zygote程式

zygote本身是一個Native的應用程式,與驅動、核心等無關。它是由init程序根據init.rc檔案中的配置建立的。zygote最初的名字叫“app_process”,這個名字是在Android.mk檔案中指定的。在執行中,app_process通過linux下的pctrl系統呼叫將自己的名字換成了zygote。

Zygote程序的建立是真正的Android執行空間,初始化建立的Service都是Navtive service。zygote讓Dalvik虛擬機器共享程式碼、低記憶體佔用以及最小的啟動時間成為可能。Zygote是Framework大家族(如system_server)的祖先。事實上,Zygote建立了第一個Java執行環境(JVM)。

zygote程序由init通過fork而來,在init.rc中設定的啟動引數如下:

-Xzygote /system/bin --zygote --start-system-server

2、Zygote建立Java世界的步驟

zygote程序啟動的前期工作:

1、建立AppRuntime物件,並呼叫它的start,之後的活動則由AppRuntime來控制。 2、呼叫startVm建立Java虛擬機器,然後呼叫startReg來註冊JNI函式。 3、通過JNI呼叫com.android.os.ZygoteInit類的main函式,從此進入Java世界。

ZygoteInit的main方法的工作:

4、呼叫registerZygoteSocket函式建立了一個socket介面,用來和ActivityManagerService通訊; 5、呼叫startSystemServer函式來啟動SystemServer元件,將系統的關鍵服務啟動起來; 6、呼叫runSelectLoopMode函式進入一個無限迴圈,等待AMS請求建立新的應用程式程序。

之後,zygote隨時等待它的子孫程序請求並隨時響應。。

9-6、SystemServer

SystemServer是Android中Java層的兩大支柱程序之一,另一個是專門負責孵化Java程序的Zygote。兩大程序中的任何一個崩潰都會導致Java層崩潰,Java層崩潰則Linux系統中的程序init會重新啟動SystemServer和Zygote,以重新建立Android的Java層。

在SystemServer.java中的init2函式中彙集了Android平臺的眾多Service。

在Android平臺中,共有7大類43個Service(包括Watchdog),7大類服務如下所示:

第1大類:是Android的核心服務,如ActivityManagerService等。
第2大類:是和通訊相關的服務,如Wi-Fi相關服務、Telephone相關服務。
第3大類:是和系統功能相關的服務,如AudioService、Usb-Service等。
第4大類:是BatteryService、VibratorService等服務。
第5大類:是EntropyService、DiskStatsService、Watchdog等相對獨立的服務。
第6大類:是藍芽服務。
第7大類:是和UI緊密相關的服務,如狀態列服務、通知管理服務等。

第5大類的部分服務分析:

EntropyService:是SystemServer啟動的第一個Service,它以3小時為單位週期性載入和儲存熵池(/dev/urandom)。系統的熵越大,該系統越不穩定。

DropBoxManagerService(DBMS):用於生成和管理系統執行時的一些日誌檔案,這些日誌檔案大多記錄的是系統或某個應用程式出錯時的資訊。

DiskStatsService:用於實現內部狀態的監控工作,DiskStatsService通常與DeviceStroageMonitorService一起實現與系統內部儲存管理和監控有關的服務。

DeviceStroageMonitorService(DSMS):用於監測系統內部儲存空間的狀態。

SamplingProfilerService:的功能是實現效能統計工作。

SystemServer分析

SystemServer是由Zygote通過Zygote.forkSystemServer函式fork出來的。通過ps命令可知程序名為system_server。

pid = Zygote.forkSystemServer();
if(pid == 0){                        //子程序返回0,即systemServer
    handleSystemServerProcess(parseArgs);
}

SystemServer的呼叫流程:

1、ZygoteInit呼叫startSystemServer建立system_server程序。 2、SystemServer呼叫handleSystemServerProcess完成自己的使命。 3、handleSystemServerProcess丟擲異常,最終呼叫com.android.server.SystemServer的main函式。 4、main函式載入libandroid_server.so並呼叫native的init1函式。 5、init1函式通過JNI呼叫com.android.server.SystemServer類的init2函式。init2函式建立一個執行緒,用於載入各種service。 6、init1函式最終加入到Binder通訊系統。

9-7、Home啟動

[email protected]後半段,系統在啟動完所有的Android服務後,使用xxx.systemReady()通知各個服務,系統已經就緒。特別是對於ActivityManagerService.systemReady(回撥)的通知,Home就是在ActivityManagerService.systemReady()通知的過程中建立的。