以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源代码的信息,看
阅读(3351) | 评论(1) | 转发(1) |