系統啓動進程
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程序所在路徑,裏面有程序源碼。因爲是可執行程序,所有必須有路徑。
commands和options比較多,不一一介紹。
由於還沒有編譯源碼,所有在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被啓動的關鍵所在。