全志平台linux啟動流程分析

2021-07-25 20:19:53 字數 3626 閱讀 5054

2015-08-02 16:31

一、brom階段

機器上電之後會執行固化在brom裡面的一段引導程式,這個程式會依次遍歷所有支援的啟動介質,直到找到第乙個支援的。目前支援的啟動介質是sd/mmc卡、nand和spinor。當程式初始化啟動介質成功後,就從固定位置讀入bootloader的boot0到sram,然後跳到sram執行。

下面展示了brom的執行流程 

二、bootloader階段

bootloader是全志平台上從小系統一直沿用下來的核心載入器,在這裡的主要職責是載入u-boot到dram。

bootloader分為兩個部分,分別是boot0和boot1。

boot0:初始化dram,載入boot1到dram;

boot1:調頻,載入u-boot到dram;

為什麼bootloader要劃分成boot0和boot1兩個部分?因為在bootloader階段,使用的sram大小是32kb,除去c執行環境需要的棧空間,可用的空間在24kb左右,這點不足以載入整個bootloader。因此,需要將bootloader劃分成兩個部分,盡可能將繁重的任務放在boot1執行,這個情況類似於linux系統中斷執行環境的上半部和下半部。

1. boot0執行過程

2. boot1的執行過程

boot1會進行一次系統調頻,將cpu的頻率調到使用者在sys_config1.fex target段配置的boot_clock。

如何在boot1讓機器進入公升級模式?

(1)按住power鍵,再按任意鍵3下;

(2)接上串列埠啟動,進入boot1後在鍵盤輸入2;

如何替換bootloader分割槽的內容?

接上串列埠啟動,進入boot1後在鍵盤輸入1,usb會掛載bootloader分割槽到pc上,卷標是「volume」,替換掉相關的檔案之後重啟機器即可生效。boot1會檢測低電關機,以及插入火牛開機的情況進入關機程式。後者需要在sys_config1.fex裡配置。

三、u-boot階段

概括地說,u-boot引導核心分為兩個階段,第一階段負責重定位u-boot到最高位址,第二階段才是真正的引導核心。

1. 第一階段

在第一階段會關閉i/d cache和mmu,因此,整個u-boot是直接執行在實體地址上。

2. 第二階段

u-boot第二階段有乙個完整、寬鬆的c環境,不再受制於棧空間,各個平台可以在這個階段完成一些複雜的操作,以求達到定製的目的。

a. board init

執行平台相關的初始化,這些比較複雜,不適宜在第一階段完成。這部分的功能在board/allwinner目錄下實現。

b. device init

主要是根據使用者的編譯配置選擇初始化對應的儲存裝置。這個地方可以改進,比如根據使用者的配置檔案

sys_config1.fex選擇初始化對應的儲存裝置。這樣可以做到乙份u-boot.bin適應不同的儲存裝置。

c. env relocate

初始化環境變數。

d. board later init

初始化fastboot和android recovery,可能修改bootcmd,影響引導流程。

e. main loop

u-boot的主程式,負責引導核心以及處理使用者的命令請求。這部分的功能在common目錄下實現。

四、核心啟動

在我們平台上使用的是非壓縮的核心(bimage),因此核心的啟動省去了自解壓的過程。核心的鏈結依賴鏈結指令碼vmlinux.lds,我們平台使用了arm的核心,對應的鏈結指令碼是arch/arm/kernel/vmlinux.lds。

1. 呼叫[email protected]查詢處理器資訊

2. 呼叫[email protected]為核心自身建立頁表

3. 呼叫處理器底層初始化函式__v7_setup@arch/arm/mm/proc-v7.s,初始化 mmu,cache,tlb

4. 呼叫[email protected]使能mmu

5. 呼叫[email protected]重定位資料段,清零bss,然後跳轉到c函式入口        

start_kernel@init/main.c,start_kernel()函式是核心初始化 c 語言部分的主體。這個函式完成系統底層基本機

制,包括處理器、儲存管理系統、程序管理系統、中斷機制、定時機制等的初始化工作。由於這個函式過於復 

雜,這裡僅闡述關鍵點。

6. 呼叫setup_arch完成架構相關的初始化

7. 呼叫pidhash_init初始化pid hast機制

8. 呼叫sched_init初始化排程器

9. 呼叫init_irq初始化中斷機制

10. 呼叫softirq_init完成軟中斷初始化

11. 呼叫local_irq_enable開啟中斷

12. 呼叫console_init完成控制台初始化

13. 呼叫rest_init

由上可知,rest_init函式建立了兩個核心執行緒,分別是kernel_init和kthreadd。kernel_init函式將完成裝置驅動

程式的初始化,並呼叫init_post函式啟動使用者空間的init程序。kthreadd的作用是管理排程其他的核心執行緒。

14. 呼叫do_basic_setup函式初始化裝置,完成外設及其驅動程式(直接編譯進核心的模組)的載入和初始化。

a. cpuset_init_smp@init/cpuset.c

建立cpuset工作佇列,它的作用是控制每個程式在哪個核心執行,對於多核的cpu。

b. usermodehelper_init@init/kmod.c

建立khelper工作佇列,它的作用是指定使用者空間的程式路徑和環境變數,最終執行user space的程式。

c. init_tmpfs@mm/shmem.c

初始化tmpfs。

d. driver_init@driver/base/init.c

初始化裝置模型。

e. init_irq_proc@kernel/irq/proc.c

初始化/proc/irq。

f. do_ctors@init/main.c

呼叫所有建構函式。

g. do_initcalls

初始化子系統。注意,.initcall.init節所儲存的函式位址有一定的優先順序,越前面的函式優先順序越高,會被先調

用。include/linux/init.h定義若干的巨集協助核心模組新增它們的初始化函式到.initcall.init節。如需控制同一優先

級的初始化函式執行順序,可以通過修改模組的makefile調動編譯鏈結順序。

15. 呼叫init_post函式啟動使用者空間的init程序。在android系統中,init程序在system/core/init目錄下實現。

init_post函式會呼叫run_init_process 執行ramdisk_execute_command,在run_init_process中,

kernel_execve負責建立使用者空間的init程序。

全志啟動流程

參考文獻 全志啟動流程可分為5部 bootrom spl uboot kernel rootfilesystem 1 spl背景 spl是乙個mini版本的uboot,類似於mtk平台的preloader,用於載入完整的uboot程式到sdrom,並通過uboot來載入核心啟動系統。spl程式流程如...

Linux啟動流程分析

linux系統從啟動到提供服務的過程是這樣,先是機器加電,然後通過mbr或者uefi載入grub,再啟動核心,核心啟動服務,然後開始對外服務。載入bios的硬體資訊與進行自我測試,並依據設定取得第乙個可啟動的裝置 比如硬碟 讀取並執行第乙個開機裝置內mbr 的boot loader 即grub2,s...

Linux啟動流程分析

1.獲取資訊 當按下電源鍵後,系統首先就會去載入bios basic input output system 並通過bios程式去載入cmos的資訊,並且藉由cmos內的設定取得主機的各項硬體配置。例如cpu與介面裝置的溝通頻率 啟動裝置的查詢順序 硬碟的大小與型別 系統時間 各周邊匯流排是否啟動p...