可执行文件组成及内存映射

可执行文件的组成

在 ADS 下,可执行文件有两种,一种是.axf 文件,带有调试信息,可供 AXD 调试工具使用.另一种是.bin

文件,可执行的二进制代码文件。我们重点是讲描.bin 文件的组成。 我们把可执行文件分为两种情况:分别为存放态和运行态。

1. 存放态

存放态是指可执行文件通过 fromelf 产生后,在存储介质(flash 或磁盘)上的分布. 此时可执行文件一 般由两部分组成:分别是代码段和数据段。代码段又分为可执行代码段(.text)和只读数据段(.rodata), 数据段又分为初始化数据段(.data)和未初始化数据段(.bss)。可执行文件的存放态如下:

+-------------+-----------

|   .bss      |

+-------------+-- 数据段

|   .data     |

+-------------+-----------

|   .rodata   |

|             | 代码段

|   .text     |

+-------------+-----------

2. 运行态

可执行文件通过装载过程, 搬入到 RAM 中运行, 这时候可执行文件就变成运行态。在 ADS 下对可执行代 码各段有另一个名称:

|    ...      |

+-------------+-----------

|   .bss      | ZI 段

+-------------+-- 数据段

|   .data     | RW 段

+-------------+-----------

|   .rodata   |

|             | 代码段(RO 段)

|   .text     |

+-------------+-----------

|    ...      |

装载前

当可执行文件装载后, 在 RAM 中的分布如下:

|    ...      |

+-------------+-- ZI 段结束地址

|    ZI 段     |

+-------------+-- ZI 段起始地址

|    保留区 2    |

+-------------+-- RW 段结束地址

|    RW 段     |

+-------------+-- RW 段起始地址

|   保留区 1     |

+-------------+-- RO 段结束地址

|    RO 段     |

+-------------+-- RO 段起始地址

|    ...      |

装载后

所以装载过程必须完成把执行文件的各个段从存储介质上搬到 RAM 指定的位置。而这个装载过程由谁来完 成呢?由我们的启动程序来完成.

装载过程

在 ADS 中,可以通过两种方式来指定可执行代码各段在 RAM 中的位置,一个是用 armlink 来指定,一种是

用 scatter 文件来指定.RAM 区的起始地址:0x30000000.

  1. armlink 指定代码段地址

我们通常的代码,只用指定两个段开始地址, RO 段的起始地址和 RW 段的起始地址, ZI 段紧接在 RW 段之

后.示例见该部分的 1.1.3.

  1. scatter 指定代码段地址

我们也可以通过 scatter 文件指定可执行文件各段的详细地址. Scatter 文件如下:

MYLOADER 0x30000000

;MYLOADER: 为可执行文件的名称, 可自定义

;0x3000000: 起始地址

{

RO 0x30000000

;RO 只读代码段的名称

;0x30000000: 只读代码段的起始地址

{

init.o (Init, +First)

; Init 代码段为可执行文件的第一部分.

* (+RO)                ;所有其它的代码段和只读数据段放在该部分

}

RW +0

;RW: RW 段的名称

;+0: 表示 RW 段紧接着 RO 段

{

* (+RW)              ;所有 RW 段放在该部分

}

ZI +0

;ZI: ZI 段的名称

;+0: 表示 ZI 段紧接着 RW 段

{

*(+ZI)                  ;所有 ZI 段放在该部分

}

}

3. ADS 产生的各代码段宏

|Image$$RO$$Base|     /* RO 代码段起始地址 */

|Image$$RO$$Limit|    /* RO 代码段结束地址 */

|Image$$RW$$Base|    /* RW 代码段起始地址 */

|Image$$RW$$Limit|   /* RW 代码段结束地址 */

|Image$$ZI$$Base|     /* ZI 代码段起始地址   */

|Image$$ZI$$Limit|    /* ZI 代码段结束地址 */

注意:在两个$$之间的名称, 与 scatter 中指定的段的名称相同.

4. 装载过程说明

当从 NorFlash 启动时, 要把 flash 芯片的首地址映射到 0x00000000 位置, 系统启动后, 启动程序本身把自己从 flash 中搬到 RAM 中运行. 搬移后的各段起始地址, 由以上宏来确定.

当从 NandFlash 启动时, S3C2410 会自动把前 NandFlash 的前 4k 搬到 S3C2410 的内部 RAM 中,并把内部 RAM 的首地址设为 0x00000000,CPU 从 0x00000000 开始执行. 所以, 在 nandFlash 的前 4k 程序中,必须包含从 NandFlash 把 BootLoader 的其余部分装入 RAM 的程序.

启动过程的汇编部分

当系统启动时, ARM CPU 会跳到 0x00000000 去执行。一般 BootLoader 都包括如下几个部分: 1.  建立中断向量异常表

2. 显示的切换到 SVC 且 32 指令模式

3. 关闭 S3C2410 的内部看门狗

4.  禁止所有的中断

5. 配置系统时钟频率和总线频率

6. 设置内存区的控制寄存器

7. 初始化中断

8. 安装中断向表量

9. 把可执行文件的各个段搬到运行态的各个位置

10. 跳到 C 代码部分执行

启动过程的 C 部分

1. 初始化 MMU 2.初始化外部端口

3. 中断处理程序表初始化

4. 串口初始化

5. 其它部分初始化(可选)

6. 主程序循环

原文地址:https://www.cnblogs.com/fanweisheng/p/11103125.html