首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

U-boot启动分析 -arm

U-boot启动分析 -arm

在了解了ARM相关的汇编指令后,同时结合网上各位大虾的提点开始阅读u-boot的启动代码,现将分析过程记录如下
可执行文件及内存映射
我们可以把可执行文件分为2种情况:存放态和运行态
1.存放态:可执行文件经过烧到存储介质上(flash或磁盘)的分布,此时可执行文件通常有2部分组成,代码段和数据段,代码段又分为可执行代码段(.text)和只读数据段(.rodata),数据段可以分为初始化数据段(.data)和未初始化代码段(.bss),如下:
+-------------+-----------
| .bss       |  (ZI)
+-------------+-- 数据段
| .data      |   (RW)
+-------------+-----------
| .rodata    |
|_____________| 代码段(RO)
| .text      |
+-------------+-----------
2.运行态:可执行文件经过装载后就变成为运行态,
当可执行文件装载后, 在RAM中的分布如下:
| ...        |
+-------------+-- ZI段结束地址
| ZI 段      |
+-------------+-- ZI段起始地址
| 保留区2    |
+-------------+-- RW段结束地址
| RW 段      |
+-------------+-- RW段起始地址
| 保留区1    |
+-------------+-- RO段结束地址
| RO 段      |
+-------------+-- RO段起始地址
所以装载过程必须完成把可执行文件的各个段搬移到RAM的指定位置,这个装载过程则是由启动程序来完成的。而可执行代码在RAM中的地址则是由链接脚本来指定的。
一个可执行的image必须有一个入口点,并且只能有一个全局入口点,所以要通知编译器这个入口在哪里。这个是有链接脚本来实现的,由此我们可以找到程序的入口点是在/board/lpc2210/u-boot.lds中指定的,其中ENTRY(_start)说明程序从_start开始运行,而他指向的是cpu/arm7tdmi/start.o文件。因为我们用的是ARM7TDMI的cpu架构,在复位后从地址0x00000000取它的第一条指令,所以我们将Flash映射到这个地址上,这样在系统加电后,cpu将首先执行u-boot程序。
ARM在CPU加电复位后是从0x0000地址开始取指,因此在零地址需要放置第一条启动代码。默认情况下,程序的链接器是把0x8000作为映像的入口点(取指的第一条指令的位置),因此需要对映像链接定位,即重定位映像段的存放,包括代码段、数据段、零区等,对整个系统的代码做正确的定位,这些规则通常写成链接脚本。链接脚本就是提供了一种把代码段和数据段放在不同存储器定位。
我们的只读代码和数据是固化在ROM中(通常在0x0000),但是在执行的时候想在RAM区运行(优化系统,使性能发挥最大),就需要链接定位。链接器告诉了随机存储器从哪里开始。
-arm" border="0">
Load View:代码编译链接的一个组织情况
Execute View:代码正确执行的空间组织
启动过程的C部分
1. 初始化MMU
2.初始化外部端口
3. 中断处理程序表初始化
4. 串口初始化
5. 其它部分初始化(可选)
6. 主程序循环
于是我们可以在链接脚本中找到映像的加载地址,也即程序的入口点。/board/s3c2410/U-boot.lds
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm","elf32-littlearm")
继承事业,薪火相传
返回列表