ARM新一期第四天

2021-09-02 22:57:33 字數 3900 閱讀 1862

一、

**為什麼需要重定向?

**測試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 ...

華為第四天

在第三天晚上下班的時候,終於搞定了第乙個專案內容,即使再簡單,我也勝利的喜悅,很欣慰,自己完成了乙個小小的任務,雖然比較簡單的乙個需求。在這種興奮的心情下,我結束了我第三天實習,我想生活始終要抱有一定的態度,是付出又收穫的喜悅,讓我們每個人都保持這種喜悅,來開始每一天的工作。第四天開始的時候,我先去...