1. 程式人生 > >ARM "重定位" 與 "分散載入" 之間的聯絡與區別

ARM "重定位" 與 "分散載入" 之間的聯絡與區別

目前剛剛學完了ARM的裸機部分,有一個問題一直比較困惑:就是 “重定位” 和 “分散載入” 到底是什麼關係?

首先結合S5PV210的啟動方式,iROM(BL0)中的程式執行完之後,將BL1(16K)從SD卡中複製到SRAM中執行,然後把BL2(剩餘的程式)複製到DDR中去執行。把BL2(剩餘的程式)複製到DDR中去執行:這個過程其實就是重定位。為什麼需要這一步重定位呢?因為程式(uboot)的大小不止16K,所以就一定要把一個程式分成兩部分,BL1和BL2,即用分散載入的方式實現重定位。S5PV210_SD卡啟動

在做裸機實驗重定位這一部分時,做過一個實驗,將SRAM中的程式重定位到DDR中。具體就是用匯編把SRAM中的程式段複製到DDR中,複製結束之後清.bss段。

// r0是程式執行地址;r1是連結地址;r2.bss段的起始地址

copy_loop:

ldr r3, [r0], #4   // 源

str r3, [r1], #4  // 目的   這兩句程式碼就完成了4個位元組內容的拷貝

cmp r1, r2       // r1r2都是用ldr載入的,都是連結地址,所以r1不斷+4總能等於r2

bne copy_loop

// 清bss段,其實就是在連結地址處把bss段全部清零

clean_bss:

ldr r0, =bss_start

ldr r1, =bss_end

cmp r0, r1// 如果r0等於r1,說明bss段為空,直接下去

beq run_on_dram// 清除bss完之後的地址

mov
r2, #0 clear_loop: str r2, [r0], #4// 先將r2中的值放入r0所指向的記憶體地址(r0中的值作為記憶體地址), cmp r0, r1// 然後r0 = r0 + 4 bne clear_loop

上面這段程式是很直觀的重定位過程,但是其實並沒有什麼作用,因為這個只是把SRAM 中自己的程式挪了個地方去執行而已。與uboot的分散載入不同的就是,這裡的重定位過程是自己寫的,而uboot的重定位是用裝置複製函式直接複製完成的。當然,uboot重定位也要自己寫清.bss段,應該是在BL2的start.S中寫。