Embedded Linux Boot Process
Embedded Linux三大要件
- Bootloader: 初始化硬體,並載入 Linux kernel
- Kernel: 系統的核心,管理整個系統的資源(排程或是記憶體管理等等),並與硬體介接
- Root filesystem: 包含了 C library, userspace application以及初始化程式 (systemd)等
The Boot Sequence
Phase1 - ROM Code
在這個時間點的外部 DRAM無法使用,因為尚未被初始化,所以當 reset / power on後要執行的程式必須存放在 SoC裡,這被稱為 ROM code。每個 SoC會有一個 on-chip ROM,在晶片生產時會燒寫一段 code進去,無法被更改,而且是 proprietary。
當晶片 reset / power on後,這段 ROM code會讀取 boot configuration pins,根據 pin的設定來決定要從哪個外部裝置載入 SPL。比方說 Xilinx UltraScale MPSoC系列的晶片可以由 QSPI, SD, NAND…等等方式開機。
ROM code具體做了哪些事情呢?
- 初始化 on-chip SRAM
- 最小限度初始化系統,比方說 SPL放在 QSPI flash,所以要初始化 QSPI controller,但在這階段不會用到網路,所以不需要初始化 NIC
- 根據 boot configuration pins從對應的外部裝置載入 SPL到 on-chip SRAM
- CPU將控制權交給 SPL
Phase2 - Secondary Program Loader
由於 on-chip SRAM空間太小的關係,所以 TPL無法在其中執行,因此需要有一個中間層來幫忙,也就是 secondary program loader (SPL)。SPL主要的任務是初始化 DRAM controller以及其他的系統必需部份,以便將 TPL載入到 DRAM中執行。通常在 SPL不會有 CLI讓 user操作,不過可能會在 console上印出一些版本和執行進度等訊息,常見的 SPL如 MLO, X-loader, FSBL等。
SPL具體做了哪些事情呢?
- 設定 pin muxing
- 初始化 clock
- 初始化 DRAM controller, UART controller
- 根據 boot configuration pins從對應的外部裝置載入 TPL到 DRAM
- CPU將控制權交給 TPL
Phase3 - Third Stage Program Loader
常見的 third stage program loader (TPL)如 U-Boot, Barebox等,可以透過 CLI讓 user來做一些的操作,像是透過 TFTP傳輸檔案、控制 GPIO、讀取 USB上的檔案、存取記憶體,但 TPL最主要的目的是要將 kernel以及 device tree載入到 DRAM中,並啟動 kernel。
TPL具體做了哪些事情呢?
- 初始化本階段要用到的硬體,例如 kernel放在 eMMC,所以需要初始化 eMMC controller
- 設定 stack pointer
- 根據 U-Boot environment中的設定去對應的外部裝置載入 kernel, device tree (DTB), root filesystem (如果使用 Ramdisk)
- 設定 kernel boot parameters
- 執行 kernel
Phase4 - Kernel
Kernel會根據 device tree去 probe對應的 platform driver或是 device driver,而 kernel開啟了哪些功能、哪些 driver需要初始化,這就要看 user在 kernel configuration中開啟了什麼功能,另外在帶有 MMU的 SoC,Kernel也會在這個階段完成 virtual memory的配置,其他像是 interrupt, scheduler , memory management等功能都會開始運作,最後,Kernel會 mount root filesystem,並執行 userspace的 init process。
Phase5 - Init System
/sbin/init作為 userspace的第一個 process,利用 systemd去帶起整個系統,哪些 service要啟動或是哪些 application在開機後要執行等等,最後就會進到登入畫面。