天天看點

Android系統啟動流程(二)

<div class="article-copyright">
				版權聲明:如需轉載請注明出處					https://blog.csdn.net/zhonglunshun/article/details/78614772				</div>
							            <div class="markdown_views">
						<!-- flowchart 箭頭圖示 勿删 -->
						<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg>
						<p>這篇文章接着上一篇文章講解<a href="http://blog.csdn.net/zhonglunshun/article/details/78605666" target="_blank" rel="external nofollow"  rel="nofollow" target="_blank">《Android系統啟動流程(二)》</a>有興趣的朋友可以傳回去看一下,有個大概的印象總是好的;</p>
           

這篇文章是對上篇文章的詳細解說;

第一步:啟動電源以及系統啟動

當電源按下,引導晶片代碼開始從預定義的地方(固化在ROM)開始執行。加載引導程式到RAM,然後執行。

第二步:引導程式

引導程式是在Android作業系統開始運作前的一個小程式。引導程式是運作的第一個程式,是以它是針對特定的主機闆與晶片的。裝置制造商要麼使用很受歡迎的引導程式比如redboot、uboot、qi bootloader或者開發自己的引導程式,它不是Android作業系統的一部分。引導程式是OEM廠商或者營運商加鎖和限制的地方。(是以從aosp上下載下傳的源碼是沒有這個引導程式的,通過aosp研究android系統的同學需要注意一下)

引導程式分兩個階段執行。

第一個階段,檢測外部的RAM以及加載對第二階段有用的程式;

第二階段,引導程式設定網絡、記憶體等等。這些對于運作核心是必要的,為了達到特殊的目标,引導程式可以根據配置參數或者輸入資料設定核心。

Android引導程式可以在\bootable\bootloader*找到。(根據廠商不同位置有所不同),比如我的源碼是6735的源碼,我的源碼中是這樣的:

zls@compiler:~/zls/source_6735/bootable/bootloader$ find -name init.s
./preloader/platform/mt6735/src/init/init.s
zls@compiler:~/zls/source_6735/bootable/bootloader$ find -name main.c
./lk/kernel/main.c
./preloader/platform/mt6735/src/core/main.c
           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

傳統的加載器包含的幾個檔案,需要在這裡說明:

init.s初始化堆棧,清零BBS段,調用main.c的_main()函數;

main.c初始化硬體(鬧鐘、主機闆、鍵盤、控制台),建立linux标簽。

對于這部分的内容,因為我也不是很懂,就不再多說,有興趣的同學可以自己去看源碼;

第三步:核心

Android核心與桌面linux核心啟動的方式差不多。核心啟動時,設定緩存、被保護存儲器、計劃清單,加載驅動。當核心完成系統設定,它首先在系統檔案中尋找init檔案,然後啟動root程序或者系統的第一個程序(init程序)。

核心到init程序啟動之間經曆了什麼?參考這篇文章:《核心啟動kernel_init(init)程序分析》

第四步: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(選項)。

在這個過程中啟動了所有rc下定義的服務,其中就有serviceManager服務,serviceManager啟動後會重新開機下面的zygote服務;

具體的啟動過程解析請參考這篇文章《Android系統init程序啟動及init.rc全解析》

在這個階段你可以在裝置的螢幕上看到“Android”logo了。

這裡有一篇擴充閱讀《SystemUI是怎麼啟動的?》

第五步:zygote

在Java中,我們知道不同的虛拟機執行個體會為不同的應用配置設定不同的記憶體。假如Android應用應該盡可能快地啟動,但如果Android系統為每一個應用啟動不同的Dalvik虛拟機執行個體,就會消耗大量的記憶體以及時間。

是以,為了克服這個問題,Android系統創造了”Zygote”。Zygote讓Dalvik虛拟機共享代碼、低記憶體占用以及最小的啟動時間成為可能。

Zygote是一個虛拟器程序,正如我們在前一個步驟所說的在系統引導的時候啟動。Zygote預加載以及初始化核心庫類。通常,這些核心類一般是隻讀的,也是Android SDK或者核心架構的一部分。在Java虛拟機中,每一個執行個體都有它自己的核心庫類檔案和堆對象的拷貝。

Zygote加載程序

加載ZygoteInit類,源代碼:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

registerZygoteSocket()為zygote指令連接配接注冊一個伺服器套接字。

preloadClassed “preloaded-classes”是一個簡單的包含一系列需要預加載類的文本檔案,位于/frameworks/base。

preloadResources() preloadResources也意味着本地主題、布局以及android.R檔案中包含的所有東西都會用這個方法加載。

在這個階段,你可以看到啟動動畫。

第六步:系統服務或服務

完成了上面幾步之後,運作環境請求Zygote運作系統服務。系統服務同時使用native以及java編寫,系統服務可以認為是一個程序。同一個系統服務在Android SDK可以以System Services形式獲得。系統服務包含了所有的System Services。

Zygote建立新的程序去啟動系統服務。你可以在ZygoteInit類的”startSystemServer”方法中找到源代碼。SystemServer.java

核心服務:

啟動電源管理器;

建立Activity管理器;

啟動電話注冊;

啟動包管理器;

設定Activity管理服務為系統程序;

啟動上下文管理器;

啟動系統Context Providers;

啟動電池服務;

啟動定時管理器;

啟動傳感服務;

啟動視窗管理器;

啟動藍牙服務;

啟動挂載服務。

其他服務:

啟動狀态欄服務;

啟動硬體服務;

啟動網絡狀态服務;

啟動網絡連接配接服務;

啟動通知管理器;

啟動裝置存儲監視服務;

啟動定位管理器;

啟動搜尋服務;

啟動剪切闆服務;

啟動登記服務;

啟動桌面服務;

啟動音頻服務;

啟動耳機監聽;

啟動AdbSettingsObserver(處理adb指令)。

第七步:引導完成

一旦系統服務在記憶體中跑起來了,Android就完成了引導過程。在這個時候“ACTION_BOOT_COMPLETED”開機啟動廣播就會發出去。

繼續閱讀