Chinaunix首页 | 论坛 | 博客
  • 博客访问: 260871
  • 博文数量: 86
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 398
  • 用 户 组: 普通用户
  • 注册时间: 2014-09-27 15:56
文章存档

2017年(3)

2015年(21)

2014年(62)

我的朋友

分类: 嵌入式

2014-11-03 22:44:25


以uboot-2012.10为例:
uboot-2012.10跳转至ram区执行指令的代码如下:

ldr r0, _board_init_r_ofs  /* 将board_init_r函数偏移值装入 r0= board_init_r - _start ,即在编译好的uboot程序中board_init_r距第一条指令的偏移 */
adr r1, _start               /* 将当前指令运行地址的第一条指令地址装入 r1中,若在ram中运行 r1 = pc + offset(_start) 若在norflash中运行 r1 = offset ,offset即为第一条指令的偏移*/
add lr, r0, r1               /* lr = pc + offset(_start)+  board_init_r - _start  运行程序空间board_init_r的物理地址 */
add lr, lr, r9               /* r9 存放的是uboot的连接地址(copy  uboot至ram的起始物理地址) */
/* setup parameters for board_init_r */
mov r0, r5 /* gd_t */
mov r1, r6 /* dest_addr */
/* jump to it ... */
mov pc, lr


_board_init_r_ofs:    /* 此处保存的是函数board_init_r 偏移位置(通俗讲:偏移第一条指令的距离)*/ 
.word board_init_r - _start

画图理解如下:


uboot代码搬移之后,在我们的系统中存在的可运行的uboot分布如上图所示有两个地方:norflash  片外ra
_board_init_r_ofs = board_init_r - _start 这个值在uboot编译成功后就是固定的值

重映射成功之后,代码暂时还在norflash中运行,想要跳转到ram区运行,就必须算出 board_init_r在ram区的位置,并跳转至这个位置继续运行(board_init_r之前的代码已经在norflash中运行了一遍,无需再运行

计算ram中board_init_r的物理地址:

上电启动情况:
首先需要明确一个概念:norflash 和 片外ram占用系统地址空间,即如果系统能正常启动硬件上已经确保norflash和片外ram的物理地址空间不会重叠。

其次计算地址使用汇编指令:   adr  /* 地址无关指令 */

ldr r0, _board_init_r_ofs  /* 将board_init_r函数偏移值装入 r0= board_init_r - _start ,即在编译好的uboot程序中board_init_r距第一条指令的偏移 */
adr r1, _start                /* 执行后 r1 =  pc + offset(_start)  此时的 pc = pc1 ( 图中的), r1 = _start 在运行设备norflah上的偏移*/
add lr, r0, r1                 /* lr = pc + offset(_start)+  board_init_r - _start  运行程序设配上board_init_r的物理地址 */
add lr, lr, r9                 /* r9 存放的是uboot的连接地址(copy  uboot至ram的起始物理地址)lr 为 board_init_r在ram上的物理地址*/

接下来的汇编就是跳转到 lr 所指向的物理地址,即 board_init_r在ram上的物理地址

至此由flash跳转至ram运行过程完成。



调试过程的运行可依此自行分析。
 
 uboot源码下载地址:
所有版本的u-boot源代码压缩包都可以在下载。
                      关于u-boot源代码的信息,看

阅读(1526) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~