重定位
為什麼需要重定位?
重定位是什麼?
怎麼實現重定位?
環境
1、s3c2440裸板
2、linux version 4.15.0
首先1、為什麼需要重定位?
s3c2440啟動有兩種方式: a、nand 啟動 b、nor啟動
nornand
可以像記憶體一樣讀,不能像記憶體一樣寫,因此當**存在全域性變數,靜態變數時,不能有效的修改這些變數的值
上電 硬體將nand**拷貝前4k到sram中,從sram開始執行,如果**大於4k,必須在前4k實現能夠將**拷貝到sdram中執行的功能
//省略了標頭檔案引入
unsigned
char bchar =
'a';
//全域性變數
intmain
(void
)return0;
}
start.s 彙編啟動檔案
/* 關閉看門狗 */
ldr r0,
=0x53000000
ldr r1,=0
str r1,
[r0]
ldr r0,
=0x4c000014
ldr r1,
=0x5
str r1,
[r0]
/*設定時鐘*/
ldr r0,
=0x4c000000
ldr r1,
=0xffffffff
str r1,
[r0]
//cpu 工作為非同步模式
mrc p15,
0,r0,c1,c0,
0 orr r0,r0,
#0xc0000000 //r1_nf:or:r1_ia
mcr p15,
0,r0,c1,c0,0
ldr r0,
=0x4c000004
ldr r1,=(
92<<12)
|(1<<4)
|(1<<0)
str r1,
[r0]
/*設定棧*/
mov r1,
#0 ldr r0,
[r1]
/* 讀出原來的值備份 */
str r1,
[r1]
/* 0->[0] */
ldr r2,
[r1]
/* r2=[0] */
cmp r1, r2 /* r1==r2? 如果相等表示是nand啟動 */
ldr sp,
=0x40000000
+4096
/* 先假設是nor啟動 */
moveq sp,
#4096 /* nand啟動 */
streq r0,
[r1]/*
重定位**:
ldr r1,
=0x30000030
ldr r2,
=0xf80
ldr r3,
[r2]
str r3,
[r1]
*/
結果:
燒寫到nand :如下圖會遞增列印
燒寫到nor中: 一直列印』a『
解決辦法:
在start.s新增如下**上面已經注釋了:
重定位**:
ldr r1,
=0x30000030
//記憶體空間 sdram中位址
ldr r2,
=0xf80
//全域性變數b_char位址,通過反彙編檢視;
ldr r3,
[r2]
str r3,
[r1]
編譯檔案的時候使用連線指令碼:
sections
//指定位址為0 開始存放**段,所有檔案**段放在這裡
.rodata :
//所有檔案唯讀段放在**段之後
.data 0x30000020:at
(0xf80
)//指定所有檔案資料段 載入位址為0xf80(即燒寫到0xf80的位置, 執行的時候在0x30000020處操作)
.bss :
}
這樣;燒寫到nand 和nor 上都可以遞增列印字元』a』 重定位的介紹
1 鏈結位址和執行位址 1 鏈結位址 2 執行位址在位置相關碼執行前,需要把 拷貝到以鏈結位址為起始位址的空間裡,然後通過跳轉語句,跳轉到以鏈結位址為起始位址的 的相應的位置繼續執行。3 舉例 2 重定位 1 在執行位址處執行一段位置無關碼,把整個程式映象拷貝乙份到鏈結位址處,然後使用長跳轉指令從執...
ORBSLAM 重定位 一
變數含義 mcurrentframe.computebow detectrelocalizationcandidates mcurrentframe step3.1對每乙個候選幀進行詞袋匹配 int nmatches matcher.searchbybow pnpsolver psolver new...
共享可寫節包含重定位 理解重定位
一 段的概念 段是程式的組成元素。將整個程式分成乙個乙個段,並且給每個段起乙個名字,然後在鏈結時就可以用這個名字來指示這些段,使得這些段排布在合適的位置。乙個程式通常包含以下五個段 段 text 存放 指令 唯讀資料段 rodata 存放有初始值並且const修飾的全域性類變數 全域性變數或stat...