在考慮為什麼要重定位的問題之前,我們首先要明白一下幾點:
1. 連結地址的定義:我自己理解是,程式被定義的開始執行的記憶體位址。
2. 當ARM從nandflash啟動的時候,CPU所做的工作是將nandflash中的前8K代碼自動的複製到6410的0地址(即Stepping Stone)中去,然後從0地址開始執行程式。
3. 程式在執行過程中,用連結地址來訪問全域變數。全域變數一般被存放於程式的最後面。
在程式超過8K時,如果不進行重定位,就會發生類似於下面的訪問錯誤,這將導致程式無法正常執行。
假設我們定義程式的連結地址為0x50000000,程式從6410的0地址(即Stepping Stone)執行的時候,如果要訪問某個全域變數時,假設其反組譯碼代碼如下:
500000a4 e59f303c ldr r0, [pc, #60] ;r0 = [0x500000e8] =0x00000200
500000a8 e5933000 ldr r0, [r0] ;r0 = [0x00000200]
500000ac ......
......
500000e8 00000200 .......
00000200 <i>:
200: 00000000 ......
我們可以看出來,r0的值要根據地址0x500000e8處獲得,而在Stepping Stone中無法找到0x500000e8這個地址,這樣程式就會出錯。所以在程式被CPU拷貝到Stepping Stone後,我們要先寫一段程式初始化nandflash和記憶體,再利用位置無關的代碼將程式從nandflash拷貝到記憶體中,然後跳轉到其它函數繼續執行,這就是ARM的重定位。
*****************************************************************************************************************************************************************************************
以上純屬個人觀點,有錯誤的地方還請大俠們指正!謝謝!