ARM移植之BootLoader(1)
BootLoader 的實現依賴于CPU的體系結構,因此大多數 BootLoader 都分為stage1 和stage2 兩大部分。依賴于CPU體系結構的代碼,比如設備初始化代碼等,通常都放在 stage1中,而且通常都用匯編語言來實現,以達到短小精悍的目的。而stage2 則通常用C 語言來實現,這樣可以實現更復雜的功能,而且代碼會具有更好的可讀性和可移植性。
BootLoader 的 stage1 通常包括以下步驟:
·硬件設備初始化;
·為加載Boot Loader的stage2準備 RAM 空間;
·拷貝Boot Loader的stage2 到RAM空間中;
·設置好堆棧;
·跳轉到 stage2 的 C 入口點。
Boot Loader的stage2通常包括以下步驟:
·初始化本階段要使用到的硬件設備;
·檢測系統內存映射(memory map);
·將kernel 映像和根文件系統映像從flash上讀到 RAM 空間中;
·為內核設置啟動參數;
·調用內核。
本系統中的BootLoader參照韓國mizi公司的vivi進行修改。
1.開發環境
我們購買了武漢創維特信息技術有限公司開發的具有自主知識產權的應用于嵌入式軟件開發的集成軟、硬件開發平臺ADT(ARM Development Tools)它為基于ARM 核的嵌入式應用提供了一整套完備的開發方案,包括程序編輯、工程管理和設置、程序編譯、程序調試等。
ADT嵌入式開發環境由ADT Emulator for ARM 和ADT IDE for ARM組成。ADT Emulator for ARM 通過JTAG 實現主機和目標機之間的調試支持功能。它無需目標存儲器,不占用目標系統的任何端口資源。目標程序直接在目標板上運行,通過ARM 芯片的JTAG 邊界掃描口進行調試,屬于完全非插入式調試,其仿真效果接近真實系統。
ADT IDE for ARM 為用戶提供高效明晰的圖形化嵌入式應用軟件開發環境,包括一整套完備的面向嵌入式系統的開發和調試工具:源碼編輯器、工程管理器、工程編譯器(編譯器、匯 編器和連接器)、集成調試環境、ADT Emulator for ARM 調試接口等。其界面同Microsoft Visual Studio 環境相似,用戶可以在ADT IDE for ARM 集成開發環境中創建工程、打開工程,建立、打開和編輯文件,編譯、連接、設置、運行、調試嵌入式應用程序。
ADT嵌入式軟件開發環境 采用主機-目標機交叉開發模型。ADT IDE for ARM 運行于主機端,而ADT Emulator for ARM 實現ADT IDE for ARM 與目標機之間的連接。開發時,首先由ADT IDE for ARM 編譯連接生成目標代碼,然后建立與ADT Emulator for ARM 之間的調試通道,調試通道建立成功后,就可以在ADT IDE for ARM 中通過ADT Emulator for ARM 控制目標板實現目標程序的調試,包括將目標代碼下載到目標機中,控制程序運行,調試信息觀察等等。
![]() |
2.ARM匯編
ARM本身屬于RISC指令系統,指令條數就很少,而其編程又以C等高級語言為主,我們僅需要在Bootloader的第一階段用到少量匯編指令:
(1)+-運算
ADD r0, r1, r2 ―― r0 := r1 + r2 SUB r0, r1, r2 ―― r0 := r1 - r2 |
其中的第二個操作數可以是一個立即數:
ADD r3, r3, #1 ―― r3 := r3 + 1 |
第二個操作數還可以是位移操作后的結果:
ADD r3, r2, r1, LSL #3 ―― r3 := r2 + 8.r1 |
(2)位運算
AND r0, r1, r2 ―― r0 := r1 and r2 ORR r0, r1, r2 ―― r0 := r1 or r2 EOR r0, r1, r2 ―― r0 := r1 xor r2 BIC r0, r1, r2 ―― r0 := r1 and not r2 |
(3)寄存器搬移
MOV r0, r2 ―― r0 := r2 MVN r0, r2 ―― r0 := not r2 |
(4)比較
CMP r1, r2 ―― set cc on r1 - r2 CMN r1, r2 ―― set cc on r1 + r2 TST r1, r2 ―― set cc on r1 and r2 TEQ r1, r2 ―― set cc on r1 or r2 |
這些指令影響CPSR寄存器中的 (N, Z, C, V) 位
(5)內存操作
LDR r0, [r1] ―― r0 := mem [r1] STR r0, [r1] ―― mem [r1] := r0 LDR r0, [r1, #4] ―― r0 := mem [r1+4] LDR r0, [r1, #4] ! ―― r0 := mem [r1+4] r1 := r1 + 4 LDR r0, [r1], #4 ―― r0 := mem [r1] r1 := r1 +4 LDRB r0 , [r1] ―― r0 := mem8 [r1] LDMIA r1, {r0, r2, r5} ―― r0 := mem [r1] r2 := mem [r1+4] r5 := mem [r1+8] |
{..} 可以包括r0~r15中的所有寄存器,若包括r15 (PC)將導致程序的跳轉。
(6)控制流
例1:
MOV r0, #0 ; initialize counter LOOP: ADD r0, r0, #1 ; increment counter CMP r0, #10 ; compare with limit BNE LOOP ; repeat if not equal |
例2:
CMP r0, #5 ADDNE r1, r1, r0 SUBNE r1, r1, r2 ―― if (r0 != 5) { r1 := r1 + r0 - r2 } |
評論