菠蘿麵包整理了 Android 開機流程 boot sequence
給個 boot rom, bootloader, Linux kernel, Android Init, Zygote, Dalvik,, System Server, 最後發出
ACTION_BOOT_COMPLETED 的 braodcast intent 觸發需要知道開機啟動的服務,其中從
硬體到使用者接觸到的應用程式的完整流程。
我們關注的是前面這段觀念:
硬體平台上的 boot ROM 儲存了 boot code,boot rom 本身也是在記憶體上執行,arm cpu
藉由 reset 0x0000, 0000 由 chip select 線路連結的開機媒介決定到哪一種 storage (Nor flash,
Nand flash) 去讀取 boot loader。 將 boot loader 載入到實體記憶體後開始執行 boot loader ...
在 booting sequence documentation 則提到在 bootloader 到 linux kernel 端的開機介面
與流程:
ARM Linux kernel 對 bootloader 所需要的,就是藉由 bootloader 將 Linux kernel 從
storage 讀出載入到記憶體,設定某些暫存器,並呼叫 Linux kernel entry point,此
時還不需要啟動 MMU。
Linux kernel 的 zImage 壓縮檔,就必須要跳到 arch/arm/boot/compressed/head.S
會使用 arch/arm/boot/compressed/misc.c (抄自 gzip 的某些函式介面) 裡面的
decompress_kernel() 其中會呼叫 arch_decomp_setup() 設定 debug FF/ST uart port,
或特殊的 Chip Select memory mapping,接著在開機印出 "Uncompressing Linux..."
字串後進行解壓縮。
ARM Linux boot sequence
另外關於 arm linux 的開機流程也有人寫了程式碼分析文:
ARM Linux boot sequence
zImage 解壓縮階段:
從跟 boot loader 串接,關閉 cpu cache, MMU, 設定 stack, kernel entry point 在實體
記憶體位置,設定 cpu 型號辨識,啟用 cpu cache, MMU, 設定 MMU page table
將 kernel zImage 解壓縮並載入到 RAM,進入 kernel start...
ARM 相關的 kernel code:
查詢 cpu 型號,啟用多核心支援,查詢(主機)板子的 machine 型號,MACHINE_DESC
macro 的定義。建立 MMU 的 page table,enable MMU,初始化 cache, write buffer。
繼續 enable MMU,設定 page table pointer (TTB),找到 page table 起始點,切換
MMU 進入 virtual address space, 回到已經過 mmap 過的 switch data。
複製 data segment 到 RAM
清空 BSS(寫零)
跳到 start_kernel 開始執行 Linux kernel 開機程序。也就是接 Intel 文件中的 C 程式碼
起始點。
Linux kernel entry points
讀 Intel 的 device driver debugging 可以找到幾個 Linux kernel source entry point。
開發新平台(OS Adaptation, OS bring up, customize core components)
其中一項重要的工作就是寫驅動程式,有些多媒體編解碼的最佳化,
也是在驅動程式端實作。
一些有用的 kernel 資訊如:active kernel threads, loaded kernel modules
x86 開機流程中 BIOS->OS boot loader --start_kernel()-->OS
sched_init() 是 scheduler initialization
mwait_idle() 是 OS 主要的迴圈(就像 micro controller 的 main loop)
相關連結:
Device Driver Debugging on Intel Atom processor based devices (pdf)