可执行文件组成及内存映射
可執(zhí)行文件的組成
在 ADS 下,可執(zhí)行文件有兩種,一種是.axf 文件,帶有調(diào)試信息,可供 AXD 調(diào)試工具使用.另一種是.bin
文件,可執(zhí)行的二進(jìn)制代碼文件。我們重點(diǎn)是講描.bin 文件的組成。 我們把可執(zhí)行文件分為兩種情況:分別為存放態(tài)和運(yùn)行態(tài)。
1. 存放態(tài)
存放態(tài)是指可執(zhí)行文件通過 fromelf 產(chǎn)生后,在存儲(chǔ)介質(zhì)(flash 或磁盤)上的分布. 此時(shí)可執(zhí)行文件一 般由兩部分組成:分別是代碼段和數(shù)據(jù)段。代碼段又分為可執(zhí)行代碼段(.text)和只讀數(shù)據(jù)段(.rodata), 數(shù)據(jù)段又分為初始化數(shù)據(jù)段(.data)和未初始化數(shù)據(jù)段(.bss)。可執(zhí)行文件的存放態(tài)如下:
+-------------+-----------
|?? .bss????? |
+-------------+-- 數(shù)據(jù)段
|?? .data???? |
+-------------+-----------
|?? .rodata?? |
| ??????????? | 代碼段
|?? .text???? |
+-------------+-----------
?
2. 運(yùn)行態(tài)
可執(zhí)行文件通過裝載過程, 搬入到 RAM 中運(yùn)行, 這時(shí)候可執(zhí)行文件就變成運(yùn)行態(tài)。在 ADS 下對(duì)可執(zhí)行代 碼各段有另一個(gè)名稱:
|??? ...????? |
+-------------+-----------
|?? .bss????? | ZI 段
+-------------+-- 數(shù)據(jù)段
?
|?? .data???? | RW 段
+-------------+-----------
|?? .rodata?? |
| ??????????? | 代碼段(RO 段)
|?? .text???? |
+-------------+-----------
|??? ...????? |
裝載前
?
當(dāng)可執(zhí)行文件裝載后, 在 RAM 中的分布如下:
?
|??? ...????? |
+-------------+-- ZI 段結(jié)束地址
|??? ZI 段???? |
+-------------+-- ZI 段起始地址
|??? 保留區(qū) 2??? |
+-------------+-- RW 段結(jié)束地址
|??? RW 段???? |
+-------------+-- RW 段起始地址
|?? 保留區(qū) 1???? |
+-------------+-- RO 段結(jié)束地址
|??? RO 段???? |
+-------------+-- RO 段起始地址
|??? ...????? |
裝載后
?
所以裝載過程必須完成把執(zhí)行文件的各個(gè)段從存儲(chǔ)介質(zhì)上搬到 RAM 指定的位置。而這個(gè)裝載過程由誰來完 成呢?由我們的啟動(dòng)程序來完成.
?
裝載過程
在 ADS 中,可以通過兩種方式來指定可執(zhí)行代碼各段在 RAM 中的位置,一個(gè)是用 armlink 來指定,一種是
用 scatter 文件來指定.RAM 區(qū)的起始地址:0x30000000.
我們通常的代碼,只用指定兩個(gè)段開始地址, RO 段的起始地址和 RW 段的起始地址, ZI 段緊接在 RW 段之
后.示例見該部分的 1.1.3.
?
我們也可以通過 scatter 文件指定可執(zhí)行文件各段的詳細(xì)地址. Scatter 文件如下:
?
MYLOADER 0x30000000
;MYLOADER: 為可執(zhí)行文件的名稱, 可自定義
;0x3000000: 起始地址
{
RO 0x30000000
;RO 只讀代碼段的名稱
;0x30000000: 只讀代碼段的起始地址
{
init.o (Init, +First)
; Init 代碼段為可執(zhí)行文件的第一部分.
* (+RO)??????????????? ;所有其它的代碼段和只讀數(shù)據(jù)段放在該部分
}
?
RW +0
;RW: RW 段的名稱
;+0: 表示 RW 段緊接著 RO 段
{
* (+RW)????????????? ;所有 RW 段放在該部分
}
?
ZI +0
;ZI: ZI 段的名稱
;+0: 表示 ZI 段緊接著 RW 段
{
*(+ZI)????????????????? ;所有 ZI 段放在該部分
}
}
?
3. ADS 產(chǎn)生的各代碼段宏
|Image$$RO$$Base|???? /* RO 代碼段起始地址 */
|Image$$RO$$Limit|??? /* RO 代碼段結(jié)束地址 */
|Image$$RW$$Base|??? /* RW 代碼段起始地址 */
|Image$$RW$$Limit|?? /* RW 代碼段結(jié)束地址 */
|Image$$ZI$$Base|???? /* ZI 代碼段起始地址?? */
|Image$$ZI$$Limit|??? /* ZI 代碼段結(jié)束地址 */
注意:在兩個(gè)$$之間的名稱, 與 scatter 中指定的段的名稱相同.
?
4. 裝載過程說明
當(dāng)從 NorFlash 啟動(dòng)時(shí), 要把 flash 芯片的首地址映射到 0x00000000 位置, 系統(tǒng)啟動(dòng)后, 啟動(dòng)程序本身把自己從 flash 中搬到 RAM 中運(yùn)行. 搬移后的各段起始地址, 由以上宏來確定.
當(dāng)從 NandFlash 啟動(dòng)時(shí), S3C2410 會(huì)自動(dòng)把前 NandFlash 的前 4k 搬到 S3C2410 的內(nèi)部 RAM 中,并把內(nèi)部 RAM 的首地址設(shè)為 0x00000000,CPU 從 0x00000000 開始執(zhí)行. 所以, 在 nandFlash 的前 4k 程序中,必須包含從 NandFlash 把 BootLoader 的其余部分裝入 RAM 的程序.
?
啟動(dòng)過程的匯編部分
當(dāng)系統(tǒng)啟動(dòng)時(shí), ARM CPU 會(huì)跳到 0x00000000 去執(zhí)行。一般 BootLoader 都包括如下幾個(gè)部分: 1.? 建立中斷向量異常表
2. 顯示的切換到 SVC 且 32 指令模式
3. 關(guān)閉 S3C2410 的內(nèi)部看門狗
4.? 禁止所有的中斷
5. 配置系統(tǒng)時(shí)鐘頻率和總線頻率
6. 設(shè)置內(nèi)存區(qū)的控制寄存器
7. 初始化中斷
8. 安裝中斷向表量
9. 把可執(zhí)行文件的各個(gè)段搬到運(yùn)行態(tài)的各個(gè)位置
10. 跳到 C 代碼部分執(zhí)行
?
啟動(dòng)過程的 C 部分
1. 初始化 MMU 2.初始化外部端口
3. 中斷處理程序表初始化
4. 串口初始化
?
5. 其它部分初始化(可選)
6. 主程序循環(huán)
?
轉(zhuǎn)載于:https://www.cnblogs.com/fanweisheng/p/11103125.html
總結(jié)
以上是生活随笔為你收集整理的可执行文件组成及内存映射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。