一、
**為什麼需要重定向?
**測試nor 和nand 區別:
#include "s3c2440_soc.h"
#include "uart.h"
#include "init.h"
char g_char = 'a';
const char g_char2 = 'b';
int g_a = 0;
int g_b;
int main(void)
return 0;
}
nor啟動全域性變數不可更改,解決辦法:
①修改makefile
arm-linux-ld -ttext 0 -tdata 0x30000000 start.o led.o uart.o init.o main.o -o sdram.elf
讓全域性變數放在基址0x30000000處(sdram基址),但是編譯出來的bin檔案非常大,八百多兆!**段和資料段之間有巨大間隔
②**段和資料段不應該有那麼大的黑洞,應該是執行的時候資料段拷貝到0x3000,0000處,而不是鏈結的時候把資料段單獨鏈結到0x3000,0000.
參考資料:
using ld, the gnu linker
兩種解決辦法:
1. 只把全域性變數重定位到sdram
修改makefile,寫乙個鏈結指令碼sdram.lds
all:
arm-linux-gcc -c -o led.o led.c
arm-linux-gcc -c -o uart.o uart.c
arm-linux-gcc -c -o init.o init.c
arm-linux-gcc -c -o main.o main.c
arm-linux-gcc -c -o start.o start.s
#arm-linux-ld -ttext 0 -tdata 0x30000000 start.o led.o uart.o init.o main.o -o sdram.elf
arm-linux-ld -t sdram.lds start.o led.o uart.o init.o main.o -o sdram.elf
#elf檔案含有位址資訊,bin檔案沒有了位址資訊
arm-linux-objcopy -o binary -s sdram.elf sdram.bin
arm-linux-objdump -d sdram.elf > sdram.dis
clean:
rm *.bin *.o *.elf *.dis
sections
.rodata :
.data 0x30000000 : at(0x800)
.bss :
}
對於.lds檔案,它定義了整個程式編譯之後的連線過程,決定了乙個可執行程式的各個段的儲存位置,格式如下:
參考文件:
bl sdram_init
/* 重定位data段 */
mov r1, #0x800
ldr r0, [r1]
mov r1, #0x30000000
str r0, [r1]
簡單粗暴,直接把0x800上的資料拷貝至0x30000000,雖然能實現效果,但是顯然不能適應所有的情況。(nor上執行沒有nand快)
在鏈結指令碼上可以新增一些變數,在start.s中使用
sections
.rodata :
.data 0x30000000 : at(0x800)
. = align(4);
bss_start = .;
.bss :
bss_end = .;
}
start.s更改如下:
/* 重定位data段 */
ldr r1, =data_load_addr /* data段在bin檔案中的位址, 載入位址 */
ldr r2, =data_start /* data段在重定位位址, 執行時的位址 */
ldr r3, =data_end /* data段結束位址 */
cpy:
ldr r4, [r1]
str r4, [r2]
add r1, r1, #4
add r2, r2, #4
cmp r2, r3
ble cpy
清除bss:
/* 清除bss段 */
ldr r1, =bss_start
ldr r2, =bss_end
mov r3, #0
clean:
str r3, [r1]//從flash中寫入記憶體
add r1, r1, #4
cmp r1, r2
ble clean//小於或者等於
2. 把全部**重定位到sdramlds檔案
sections
. = align(4);
.rodata :
. = align(4);
.data :
. = align(4);
__bss_start = .;
.bss :
_end = .;
}
start.s檔案
/* 重定位text, rodata, data段整個程式 */
mov r1, #0
ldr r2, =_start /* 第1條指令執行時的位址 */
ldr r3, =__bss_start /* bss段的起始位址 */
cpy:
ldr r4, [r1]
str r4, [r2]
add r1, r1, #4
add r2, r2, #4
cmp r2, r3
ble cpy
/* 清除bss段 */
ldr r1, =__bss_start
ldr r2, =_end
mov r3, #0
clean:
str r3, [r1]
add r1, r1, #4
cmp r1, r2
ble clean
//bl main /* 使用bl命令相對跳轉, 程式仍然在nor/sram執行 */
ldr pc, =main /* 絕對跳轉, 跳到sdram */
重定位_清除bss段的c函式實現c**中如何使用鏈結指令碼中定義的變數
參考文章:
c函式怎麼使用lds檔案中的變數abc?
a. 在c函式中宣告改變量為extern型別, 比如:
extern int abc;
b. 使用時, 要取址, 比如:
int *p = &abc; // p的值即為lds檔案中abc的值
新一期ARM作業 六 Nor Flash
目錄描述 解答實現乙個關中斷 開中斷的函式,在測試nor flash時關中斷,測完後開中斷。這樣就不需要注釋掉timer的中斷函式了 第003節 norflash程式設計 擦寫讀,這個程式寫得不好,應該把nor read,nor write,nor erase單獨實現出來,現在都是內嵌在do rea...
開課第四天
今天是開課的第四天,老師又講了很多知識 1 位運算 位運算的效能高,但是理解比較困難。1 按位與,兩個都是一才為一,兩個不一樣就為零。2 按位或,只要有乙個是一就是一。3 異或,不同為一,乙個數和另乙個數異或倆次還是它自己,乙個數和自身異或結果是零,乙個數和零異或結果還是它本身。對稱加密,解密。4 ...
華為第四天
在第三天晚上下班的時候,終於搞定了第乙個專案內容,即使再簡單,我也勝利的喜悅,很欣慰,自己完成了乙個小小的任務,雖然比較簡單的乙個需求。在這種興奮的心情下,我結束了我第三天實習,我想生活始終要抱有一定的態度,是付出又收穫的喜悅,讓我們每個人都保持這種喜悅,來開始每一天的工作。第四天開始的時候,我先去...