ARM "重定位" 與 "分散載入" 之間的聯絡與區別
阿新 • • 發佈:2018-11-08
目前剛剛學完了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 // r1和r2都是用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中寫。