本文主要介绍了在ARM嵌入式系统开发中,尤其是使用RealView工具链时,~main函数内部的细节和加载/执行视图转换的过程。作者通过分析一个示例工程getting-started-project-at91sam9261-ek,展示了如何从源代码层面理解~main函数的工作机制。
首先,~main函数并不直接被调用,而是经过了复制重定位区(Region Table)和零初始化ZI节的处理。这个过程涉及以下几个关键步骤:
1. **复制重定位区和ZI节**:
- `scatterload—rt2`函数负责加载Region Table Base和Limit到寄存器,以便后续访问区域表。
- `scatterload—null`函数遍历区域表,调用`scatterload—copy`用于复制Relocate-region到特定地址(0x300000),以及调用`scatterload—zeroinit`来初始化大小为0x12C的ZI节(零初始化区)。
2. **~main函数的执行流程**:
- `main`函数通过`scatterload—rt2`调用`scatterload—null`,然后加载和初始化内存区域。
- `scatterload—null`检查R10和Rll是否已处理完Region Table的所有条目,如果没有,继续加载数据和调用处理函数,如`scatterload—copy`和`scatterload—zeroinit`。
- 完成这些操作后,R10和Rll指向相同,程序进入`rt entry`函数,为堆栈和堆分配内存,并初始化C运行时库,最后调用真正的`main`函数。
3. **映像文件的构建**:
- C源代码经过预处理、编译和链接三个步骤生成可执行映像文件。链接器生成的链接地址映射文件包含节、符号表和存储器映射等信息,以支持分散加载。
4. **分散加载机制**:
- RealView工具链使用分散加载机制,如sdram.sct文件,将关键代码和频繁访问数据定位到访问速度更快的存储器(如外部SDRAM),以提升系统效率。
5. **加载视图与执行视图的区别**:
- 加载视图是映像文件在内存中的组织形式,而执行视图则是程序实际运行时的内存布局。理解两者之间的转换有助于深入理解程序的初始化过程。
通过这些细节,本文帮助读者深入理解了嵌入式系统中~main函数的执行前的准备工作,以及映像文件管理和内存管理的重要性。这对于开发人员优化代码性能和系统理解具有重要意义。