實驗引導:
在main函數中引入全局變量a時,若將連接后的文件燒寫在nand flash上,則可以訪問修改全局變量a,若將連接后的文件燒寫在nor flash上,則只可訪問a,不能修改a。這是由于燒寫在nand flash 上的代碼會被加載到4K的片內內存SRAM上,全局變量a放在內存里是可讀可寫的;但將代碼燒寫在nor flash上時,cpu可以直接通過內存控制器來訪問nor flash,然而全局變量在nor flash中是不可修改的,因此需要重定位代碼,即將全局變量a,或者是整段代碼重定位到SDRAM中,這樣就能讀寫全局變量了。
概念梳理:
加載地址:指二進制.bin文件燒寫時的地址,默認從零地址開始
運行時地址:指程序在真正運行時的地址
絕對跳轉:在代碼進行跳轉時采用的是絕對地址,訪問全局變量時采用絕對跳轉
相對跳轉:在代碼進行跳轉時采用的是相對地址,即匯編中的B/BL命令跳轉
重定位步驟:1.指定代碼的運行地址 2 將代碼從加載地址復制到運行時地址。若采用將全部代碼重定位,則在跳轉到main時,需要使用絕對跳轉(ldr pc,=main)才能使程序運行在SDRAM中,否則代碼還是運行在加載地址。
注意點:在復制代碼時,如果是以byte為單位復制并且以byte為單位讀數據,則無需考慮字節對齊;但若是以4*byte為單位,則需注意字節對齊,否則有可能導致數據被破壞。
段分類說明:
.text :代碼段
.data:數據段,存放已經初始化了的全局變量
.rodata:只讀數據段,存放靜態常量(const修飾)
.bss:存放未初始化或者初始化為0的全局變量
.初始化.bss段:
.bss段并不會被程序自動初始化,因此不會在內存中有.bss段,需要人為地添加.bss段,并且對其初始化為0。
鏈接腳本:
重定位運行時地址和加載地址的指定,是通過鏈接腳本實現的。以下代碼為例子:
SECTIONS
{
. = 0x30000000;
. = ALIGN(4);
.text :
{
*(.text)
}
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) *(.COMMON) }
_end = .;
}
知識點補充
:鏈接腳本在被編譯時會產生符號表,里面存儲了定義的各個標簽極其位置的信息,在使用c語言進行編程時,將標簽用extern聲明為外部引用,然后進行取地址就能得到該地址了。
說明:本筆記只用于筆者個人總結知識點,指導意義有限,若有同樣學習了韋老師視屏的同學,歡迎相互交流。
上一篇:S3C2440 代碼重定位實驗(一)
下一篇:MY2410開發板(S3C2410)INC文件1----2410addr.h
推薦閱讀
史海拾趣