Android裝置的啟動必須經曆3個階段。即BootLoader,Linux Kernel和Android系統服務,預設情況下它們都有各自的啟動畫面。嚴格來說,Android系統實際上是運作于Linux核心之上的一系列“服務程序”,這些程序是維持裝置正常工作的關鍵,而它們的“老祖宗”就是init。作為android系統第一個被啟動的程序,init的PID值為0。它通過解析init.rc腳本來建構出系統的初始運作形态。當你按下電源開關後Android裝置執行了以下步驟。
第一步:啟動電源以及系統啟動
當電源按下,引導晶片代碼開始從預定義的地方(固化在ROM)開始執行。加載引導程式到RAM,然後執行。
第二步:引導程式
引導程式是在Android作業系統開始運作前的一個小程式。引導程式是運作的第一個程式,是以它是針對特定的主機闆與晶片的。裝置制造商要麼使用很受歡迎的引導程式比如redboot、uboot、qi bootloader或者開發自己的引導程式,它不是Android作業系統的一部分。引導程式是OEM廠商或者營運商加鎖和限制的地方。
引導程式分兩個階段執行。第一個階段,檢測外部的RAM以及加載對第二階段有用的程式;第二階段,引導程式設定網絡、記憶體等等。這些對于運作核心是必要的,為了達到特殊的目标,引導程式可以根據配置參數或者輸入資料設定核心。
Android引導程式可以在\bootable\bootloader\legacy\usbloader找到。
傳統的加載器包含兩個檔案,需要在這裡說明:
init.s初始化堆棧,清零BBS段,調用main.c的_main()函數;
main.c初始化硬體(鬧鐘、主機闆、鍵盤、控制台),建立linux标簽。
第三步:核心
Android核心與桌面linux核心啟動的方式差不多。核心啟動時,設定緩存、被保護存儲器、計劃清單,加載驅動。當核心完成系統設定,它首先在系統檔案中尋找”init”檔案,然後啟動root程序或者系統的第一個程序。
第四步:init程序
init是第一個程序,我們可以說它是root程序或者說有程序的父程序。init程序有兩個責任,一是挂載目錄,比如/sys、/dev、/proc,二是運作init.rc腳本。
init程序可以在/system/core/init找到。
init.rc檔案可以在/system/core/rootdir/init.rc找到。
readme.txt可以在/system/core/init/readme.txt找到。
對于init.rc檔案,Android中有特定的格式以及規則。在Android中,我們叫做Android初始化語言。
Android初始化語言由四大類型的聲明組成,即Actions(動作)、Commands(指令)、Services(服務)、以及Options(選項)。
Action(動作):動作是以指令流程命名的,有一個觸發器決定動作是否發生。
文法
on <trigger>
<command>
<command>
<command>
Service(服務):服務是init程序啟動的程式、當服務退出時init程序會視情況重新開機服務。
service <name> <pathname> [<argument>]*
<option>
<option>
...
Options(選項)
選項是對服務的描述。它們影響init程序如何以及何時啟動服務。
Action/Service | 描述 |
on early-init | 設定init程序以及它建立的子程序的優先級,設定init程序的安全環境 |
on init | 設定全局環境,為cpu accounting建立cgroup(資源控制)挂載點 |
on fs | 挂載mtd分區 |
on post-fs | 改變系統目錄的通路權限 |
on post-fs-data | 改變/data目錄以及它的子目錄的通路權限 |
on boot | 基本網絡的初始化,記憶體管理等等 |
service servicemanager | 啟動系統管理器管理所有的本地服務,比如位置、音頻、Shared preference等等… |
service zygote | 啟動zygote作為應用程序 |
在init中啟動起來的服務按照init.rc中的先後順序,大緻有:
console: start a shell,code path: system/bin/sh,其源碼中包含常用的shell指令,如ls,cd等。
adbd: start adb daemon,通常帶有disabled的選項,表明需要按名字啟動,code path:system/bin/adb。
servicemanager:這個服務管理着系統内所有binder services。code path: frameworks/base/cmds/servicemanager。
Vold: android 的udev,code path: system/vold。
Netd: start ntd daemon, code path: system/netd。
Debuggerd: start debug system, code path: system/core/debuggerd。
zygote: ['zaigəut]這是一個非常重要的服務,稍後詳解。start Android Java Runtime and start systemserver。code path:frameworks/base/cmds/app_process。
media: add AudioFlinger,AudioPolicyService,MediaPlayerService and CameraService to servicemanager,
同時啟動管理binder通訊的機制,依靠這兩個類來完成binder機制在android中間層所展現的功能:ProcessState 和IPCThreadState。Code path:frameworks/base/media/mediaserver。
bootanim: 開機動畫和鈴聲,code path:frameworks/base/cmds/bootanimation。
接下來就是關于modem的服務,如:ccci_fsd、ccci_mdinit、pppd_gprs、pppd、gsm0710muxd、muxtestapp、sockcli、socksrv、muxreport、ril-daemon等,除了前面2個,後面的都帶有disabled的參數,需要按名啟動。
Installd: start install package daemon, code path:
frameworks/base/cmds/installd。
後面還有很多關于其他硬體的服務,比如BT、WIFI等。
從這裡可以看出,linux的init在啟動若幹守護程序之後,就啟動了Android的runtime和zygote,zygote再啟動虛拟機,系統服務,系統服務再啟動完本地服務後,又啟動了若幹Android服務,并完成向ServiceManager的注冊工作,最後系統啟動完成。Servicemanager和zygote程序就奠定了Android的基礎。Zygote這個程序起來才會建立起真正的Android運作空間,初始化建立的Service都是Navtive service。系統的程序空間如下圖所示:
可見,由zygote孵化器為各程序以寫時複制的方式用最小的代價實作了虛拟機。zygote服務,這個服務會啟動一個叫做zygote的程序,zygote是Android世界的萬物之源,是以的程序都有它孵化。在啟動zygote時又會啟動System Server程序,System Server是所有系統服務的栖息地,也是應用與Zygote程序通信的中樞,例如需要啟動某個應用時會通過System Server通知zygote fork一個新的程序。在System Server啟動之後會調用com_ android_ server_ SystemServer. cpp類中的android_server_SystemServer_nativeInit函數,在該函數中會擷取ServiceManager執行個體以及啟動一些Native服務。最後會調用SystemServer内部類ServerThread的initAndLoop函數将WindowManagerService、ActivityManagerService等系統服務注冊到ServiceManager中,這些服務為系統提供各種各樣的功能,最後啟動系統消息循環,此時Android的運作環境基本建構起來了。
核心服務:
啟動電源管理器;
建立Activity管理器;
啟動電話注冊;
啟動包管理器;
設定Activity管理服務為系統程序;
啟動上下文管理器;
啟動系統Context Providers;
啟動電池服務;
啟動定時管理器;
啟動傳感服務;
啟動視窗管理器;
啟動藍牙服務;
啟動挂載服務。
其他服務:
啟動狀态欄服務;
啟動硬體服務;
啟動網絡狀态服務;
啟動網絡連接配接服務;
啟動通知管理器;
啟動裝置存儲監視服務;
啟動定位管理器;
啟動搜尋服務;
啟動剪切闆服務;
啟動登記服務;
啟動桌面服務;
啟動音頻服務;
啟動耳機監聽;
啟動AdbSettingsObserver(處理adb指令)。
一旦系統服務在記憶體中跑起來了,Android就完成了引導過程。在這個時候“ACTION_BOOT_COMPLETED”開機啟動廣播就會發出去。
第五步:Home啟動