1 bootloader
對於一般的arm處理器,cpu上電或復位執行第一條指令所在位址,即第一段程式bootloader的開始位址,bootloader一般存於nor-flash(xip),支援晶元內執行。
bootloader的功能可總結為:1)初始化cpu時鐘,記憶體,串列埠等。2)設定linux啟動引數。3)載入linux核心映象。android原始碼位於根目錄下的/bootable資料夾。
系統正常啟動,執行bootloader,初始化晶元,根據設定的啟動引數cmdline,載入linux核心映象,將控制權交給核心。
系統在bootloader模式下(非正常啟動模式),可使用fastboot, mmcboot等工具燒寫核心和檔案系統,順便提一下,android手機分割槽一般分為核心區boot.img,系統區system.img,使用者資料區userdata.img,資料恢復區recovery.img等。
2 linux核心映象
核心映象被載入到記憶體,首先進行自解壓,zimage, bzimage或uimage的頭部都內嵌有解壓縮程式,最終將核心解壓到記憶體的指定位置,開始執行核心。
3 啟動核心
原始碼位於/kernel/init/main.c,線索可歸納為:啟動核心start_kernel() => 初始化linux各大模組 + rest_init() => 開啟核心執行緒kthreadd和kernel_init() => 初始化裝置驅動程式do_basic_setup() + init_post() => 開啟第乙個使用者程序init。
3.1 start_kernel()
原始碼位於/kernel/init/main.c的start_kernel()函式,完成初始化linux系統的程序管理,記憶體管理,檔案系統等工作,可以說個個都是重量級的工作。
這裡有必要解釋下核心選項,因為linux各個子系統的初始化都建立在核心選項的解析之後。
parse_early_param();
parse_args("booting kernel", static_command_line, __start___param,
__stop___param - __start___param, &unknown_bootoption);
1) 核心選項的註冊
通過__early_parm(str, fn)或__setup(str, fn)巨集來註冊。兩者都呼叫__setup_param巨集實現,它將註冊的核心選項str所關聯的函式fn存放到.init.setup節。
2) 核心選項的解析
兩次註冊對應兩次解析,即parse_early_param()和parse_param(),解析時,會在__setup_start和__setup_end之間查詢核心選項,當識別有核心選項時,即會呼叫相應的處理函式。核心解析完後,各個子系統的初始化就可通過kernel_init()=>do_basic_setup()=>do_initcalls()來完成。
3.2 reset_init()
開啟核心執行緒kthreadd和kernel_init,kthreadd用來執行kthread_create_list全域性鍊錶中的kthread,然後建立idle執行緒來占用掉cpu空閒的時間片。
核心執行緒又叫守護程序,關於核心執行緒和linux普通程序的區別,歸納為以下三點:
3.3 kernel_init()
此時與體系相關的部分已經初始化完成,do_basic_setup()開始初始化裝置,完成外設及驅動程式(直接編譯進核心的模組)的載入和初始化。
3.4 init_post()
開啟init使用者程序,所謂android的啟動流程從這裡才剛剛開始。
android部分的啟動流程參考
android 啟動模式
啟動模式是通過在androidmanifest.xml中activity標籤中的launchmode設定的 android launchmode指示應該如何載入乙個activity.總共有四種啟動模式,他們一般配合activity啟動標記 flag activity 常量 一起使用來決定當載入乙個a...
android 啟動退出
由於android的退出,系統真不好說,比如按home鍵或者是正常退出,又比如被系統殺掉。強制退出的方法網上挺多,但確實不太符合開發規範。比如 普通standardmode的activity之間,是會保持住棧之間的順序的。這個時候需要自己恢復資料。我認為程式啟動後,activity的方式可以如下 a...
Android開機啟動
android 手機在啟動的過程中會觸發乙個standard broadcast action,名字叫 android.intent.action.boot completed 只會觸發一次 在這裡我們可以通過構建乙個廣播接收者來接收這個這個action.下面我就來簡單寫以下實現的步驟 第一步 在a...