總結:代碼重定位


什么是重定位?為什么要代碼重定位?
要弄清楚上面的這兩個問題,首先要理解下面這幾個概念
一、編碼
(1)位置無關編碼:PIC,可執行程序運行時與代碼在內存中的地址無關,代碼中沒有使用絕對地址,而是使用的相對地址。(例如:B、BL、MOV等指令)
(2)位置有關編碼:可執行程序運行時與代碼在內存中的地址有關系。(例如:LDR PC, =MAIN等指令)
 
二、地址
(1)鏈接地址:程序編譯鏈接時指定的地址(使用makefile或者鏈接腳本可以指定鏈接地址)
(2)運行地址:程序在內存中實際運行的地址。
 
三、S5PV210的啟動
       在uboot中的啟動方式,將整個uboot分為2個部分(BL1和BL2),是分別加載到內存中去運行的。在這個過程中,程序的鏈接地址和運行地址就很可能不是相同的了,但是在代碼中又有一些位置有關碼,為了使得程序可以正常的運行,就必須使用重定位來解決。(關於S5PV210的啟動在另一篇文章里有介紹)
 
四、如何重定位?
1、鏈接腳本指定鏈接地址
2、判斷運行地址和鏈接地址是否相同
3、復制代碼到指定的鏈接地址處,使用長轉移指令進行跳轉
具體的實現如下:
【鏈接腳本代碼】
 1 SECTIONS
 2 {
 3     . = 0xd0024000;
 4     
 5     .text : {
 6         start.o
 7         * (.text)
 8     }
 9 
10     .data : {
11         *(.data)
12     }
13     
14     bss_start = .;
15     .bss : {
16         * (.bss)
17     }
18     
19     bss_end = .;
20 }

【重定位代碼】

adr r0, _start         // 短加載,獲取_start的運行地址
ldr r1, =_start        // 長加載,獲取_start的鏈接地址
ldr r2, =bss_start   // 獲取bss鏈接地址,重定位代碼的結束地址
cmp r0, r1             // 比較_start的運行地址和鏈接地址是否相等
beq clean_bss        // 相等:不需要重定位;跳轉到clean_bss
                        // 不相等:需要重定位;繼續往下執行
                           
// 匯編實現while完成代碼賦值到重定位地址                           
copy_loop:
    ldr r3, [r0], #4       // 源
    str r3, [r1], #4       // 目的 先把r3中的內容放入r1的指向的地址;
    cmp r1, r2              // 然后r1 =r1 + 4
    bne copy_loop

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM