DDR=Double Data Rate雙倍速率同步動態隨機儲存空間。嚴格的說DDR應該叫DDR SDRAM,人們習慣稱為DDR,
現在我們來分析一下DDR的初始化
一個程式分為:程式碼片段、資料區段、BSS段
程式碼片段:指令之類的東西
資料區段:有初始值並且初始值不為0的全域變數或者靜態變數
BSS段:初始值為0或者無初始值的全域變數和靜態變數例如:
volatile int i = 0;
volatile int j = 0x12345678;
volatile int k = 0;
volatile int g;
/* gpm0,1,2,3設為輸出引腳 */
*gpmcon = 0x1111;
i、k、g存在於BSS段裡面
j存在於資料區段裡面
而對於*gpmcon = 0x1111;來說合適這存在於程式碼片段中
先對程式的燒寫瞭解一下:
1、 我們的程式一開始是燒寫在nand flash上的
2、 當我們設定為nand啟動後,6410片內有8K的記憶體,CPU會通過內部硬體將nand flash 前8K的內容複寫到RAM(起始地址為00000000)中去執行。
現在有一個問題就是我們寫的程式超過了8K怎麼辦呢?
如果我們的程式超過了8K的話,那我們就需要用到DDR了,然後把整個程式拷貝到DDR中去,那麼我們把程式拷貝到DDR的哪個地方呢,我的DDR有256M的空間,這時候就需要用到連結地址了,也就是會把程式複製到連結地址去。
舉個連結指令碼的例子吧。
SECTIONS //表示段
{
. = 0x5000; /**. 表示當前地址,給它賦地址為0x5000也就是整個程式的連結地址**/
.text: { /** .text 段名自己可以任意修改 ********/
start.o /** start.o表示整個start.o檔案(包括代碼、資料、BSS段)**/
*(.text) /** 存放其他所有檔案的程式碼片段 **/
}
.data: { /** 資料區段**/
*(.data) /** 其他所有檔案的資料區段**/
}
bss_start =.; /*定義變數,並且給變數bss_start賦值為當前地址(當前地址就是順序排放下來的地址) */
.bss: {
*(.bss) /** 其他所有檔案的Bss段**/
}
bss_end = .; /** 定義變數,並且給變數bss_end賦值為當前地址,同樣當前地址就是順序排放下來的地址最後一個bss之後的地址6 **/
}
注釋已經非常詳細
重定位:關於重定位的理解,我們剛才已經說了
當我們設定的連結地址不在0x0000000的時候(比方說0x50000000)就需要進行重定位,即:在硬體把原來的程式複製到內部8K的RAM中之後,因為連結地址不在0x00,所以重定位功能就會將程式複製到起始地址為0x50000000的位置去
顯然在重定位完成之前,肯定也要運行一段代碼,那麼為什麼這段代碼能夠運行呢,這就涉及到另外一個概念----位置無關碼,因為使用位置無關碼(所謂的位置無關碼就是任意串連位置都能夠啟動並執行)寫的
位置無關碼的使用:
1、 跳轉的時候使用相對指令b、bl
2、 不訪問全域變數、靜態變數
總結一下:
1、 程式啟動並執行時候應該位於它的連結地址;假設它的連結地址為0x50000000
2、 硬體決定了程式一開始從0開始運行,所以需要用到重定位(前面一小段代碼把程式複製到連結地址)
3、 前面一小段代碼為何能運行,因為用的是位置無關碼(b、bl指令)
最後來分析一下整個程式的啟動過程:
1. 假設我們把產生的axf映像檔案燒寫到nand flash中去,設定的連結地址為0x00000100
2. 一上電片內硬體自動把8K拷貝到OK6410片內記憶體中
3. 然後從地址零處開始運行
4. 接著重定位將程式轉移到連結地址處
5. 最後使用位置相關碼BL跳轉到串連處執行就OK了.
之後在這裡執行程式0x100 位置相關碼在這裡進行跳轉 0x00000000 |
|