210 likes | 394 Views
BootLoader 分析. 蔡維庭 4970E028 陳典杰 4970E055 康有成 4970E004. bootLoader 的作用(一般 PC ).
E N D
BootLoader 分析 蔡維庭4970E028 陳典杰4970E055 康有成4970E004
bootLoader 的作用(一般PC) • PC中的引導載入程式由 BIOS 和位於硬碟 MBR 中的 OS Boot Loader 一起組成。BIOS在完成硬體檢測和資源分配後,將硬碟 MBR 中的 Boot Loader 讀到系統的 RAM 中,然後將控制權交給 OS Boot Loader。Boot Loader 的主要執行任務就是將核心映像從硬碟上讀到 RAM 中,然後跳轉到核心的入口點去執行,也即開始啟動作業系統。
bootLoader 的作用(嵌入式系統) • (1)、初始化硬體設備 • (2)、建立記憶體空間的映射圖 • (3)、完成核心的載入,為核心設定啟 動參數
bootLoader 程式結構框架 • 嵌入式系統中的boot Loader 的實現完全依賴於 CPU 的體系結構,因此大多數 BootLoader 都分為第一階段和第二階段兩大部分,依賴於CPU 體系結構的程式,比如設備初始化程式等,通常都放在階段1 中,而且通常都用組合語言來實現,以達到高效能的目的。而階段2 則通常用C 語言來實現,這樣可以實現一些複雜的功能,而且程式會具有更好的可讀性和可攜性。
Boot Loader 的階段1 • 硬體設備初始化 • 複製 Boot Loader 的程式到RAM 空間中 • 設定好堆疊 • 跳轉到階段 2 的C 入口點。
Boot Loader 的階段2 • 初始化本階段要使用到的硬體設備 • 系統記憶體映射(memory map) • 將 kernel 映射和根檔案系統映射從Flash 讀到RAM 空間中 • 為核心設定啟動參數 • 調用核心
基本的硬體初始化 • 初始化 GPIO 功能,通過GPIO 來驅動LED,其目的是表明系統的狀態是OK 還是Error。如果板子上沒有LED,那麼也可以通過初始化UART 向串列埠列印Boot Loader 的Logo字元資訊來完成這一點。 • 設定 CPU 的速度和clock 頻率。 • 記憶體控制單元初始化。包括正確地設定系統動靜態記憶體控制器的各個暫存器等。
基本的硬體初始化 • 將bootLoader 程式載入到RAM 空間 • 設定堆疊指標sp • 堆疊指標的設定是為了執行 C 語言程式作好準備。通常我們可以把sp 的值安排在RAM空間的最頂端(堆疊向下生長)。此外,在設定堆疊指標sp 之前,也可以關閉led 燈,以提示準備跳轉到階段2。
設定堆疊指標sp • 跳轉到階段2 的C 入口點 • 在上述一切都就緒後,就可以跳轉到Boot Loader 的階段2 去執行了。在ARM 系統中, 可以通過修改 PC 暫存器為合適的位址來實現。
跳轉到階段2 的C 入口點 • 在上述一切都就緒後,就可以跳轉到Boot Loader 的階段2 去執行了。在ARM 系統中,可以通過修改 PC 暫存器為合適的位址來實現。
Boot Loader 階段2 分析 • 階段 2 的程式通常用C 語言來實現,以便於實現更複雜的功能和取得更好的程式可讀性和可攜性。但是與普通C 語言應用程式不同的是,在編譯和鏈結Boot Loader 程式時,不能使用glibc 庫中的任何支援函數。可以直接把main()函數的起始位址作為整個階段2 執行映射的入口點。
本階段初始化的硬體設備 • 初始化至少一個串列埠,以便和終端使用者進行 I/O 輸出資訊 • 初始化計時器 • 初始化網路傳輸等
系統的記憶體映射 • 所謂記憶體映射就是指在整個 4GB 物理位址空間中有哪些位址範圍被分配用來定址系統RAM 單元。雖然CPU 通常預留出一大段足夠的位址空間給系統RAM,但是在搭建具體的嵌入式系統時卻不一定會實現CPU 預留的全部RAM 位址空間。也就是說,具體的嵌入式系統往往只把CPU 預留的全部RAM 位址空間中的一部分映射到RAM 單元上。開發板bootloader 程式利用map __bsetup parts[]結構體對記憶體的分配進行設定,從記憶體分佈可以看PXA27X 開發板SRAM 和SDRAM 起始位址的儲存。
系統的記憶體映射 • 分佈情況: • bootloader: 0x00000000_0x00040000,共占256K,SDRAM 起始位址:0xA1E00000 • kernel: 0x00040000_0x00180000,共占1.25M,SDRAM 起始位址:0xA0008000 • root: 0x00180000_0x02000000,共占30.5M,SDRAM 起始位址:0xA0000000
載入核心映射和根檔案系統映射 • 規劃記憶體佔用的佈局 • 這裡包括兩個方面: • ① 核心映射所佔用的記憶體範圍 • ② 根檔案系統所佔用的記憶體範圍。 • 在規劃記憶體佔用的佈局時,主要考慮基底位址和映射的大小兩個方面。
載入核心映射和根檔案系統映射 • 對於核心映射,一般將其複製到從(MEM_START+0x8000)這個基底位址開始的大約1MB 大小的記憶體範圍內(嵌入式Linux 的核心一般都不操過1MB)。為什麼要把從MEM_START 到MEM_START+0x8000 這段32KB大小的記憶體空出來呢?這是因為Linux核心要在這段記憶體中放置一些全局資料結構,如:啟動參數和核心頁表等資訊。而對於根檔案系統映射,則一般將其複製到 MEM_START+0x00100000 開始的地方。 • 如果用Ramdisk 作為根檔案系統映射,則其解壓後的大小一般是1MB。
設定核心的啟動參數 • 將核心映射和根檔案系統映射複製到RAM 空間中後,就可以準備啟動Linux核心了。但是在調用核心之前,應該作一步準備工作,即:設定Linux 核心的啟動參數。 Linux2.4.x 以後的核心都傾向以標記列表(tagged list)的形式來傳遞啟動參數。啟動參數標記列表以標ATAG_CORE 開始,以標記ATAG_NONE 結束。每個標記由tag_header 結構和隨後的特定參數值資料結構來組成。
調用核心 • Boot Loader 調用Linux 核心的方法是直接跳轉到核心的第一條指令處,也即直接跳轉 • 到 MEM_START+0x8000 位址處。在跳轉時,下列條件要滿足:
調用核心 • CPU 暫存器的設定: • R0=0 • R1=機器類型ID • R2=啟動參數標記列表在RAM 中起始基底位址
調用核心 • CPU 模式: • 必須禁止中斷(IRQs 和FIQs) • CPU 必須SVC 模式
調用核心 • Cache 和MMU 的設定: • MMU必須關閉 • 指令 Cache 可以打開也可以關閉 • 資料 Cache 必須關閉