免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 778 | 回复: 0
打印 上一主题 下一主题

U-Boot中的地址问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-24 20:00 |只看该作者 |倒序浏览
    今天仔细研究了一下U-Boot(版本1.3.2)启动问题中和地址相关的一些问题,写出来和大家分享。不对的地方大家提出来讨论,交流!

    大家都知道bootloader启动分为两个阶段,stage1和stage2,这里就不多说了,直入正题。

    首先是PXA270平台上。系统上电后运行的第一段程序在cpu/pxa/start.S中,我们来看看代码:
    第一步是使系统进入SVC模式(为什么要进入SVC模式,请参考
ARM Linux Kernel Boot Requirements
)。然后,执行了一个跳转指令
    bl cpu_init_crit
这就是我们今天要关注的重点了。
    请注意,对pxa270来说,上电以后运行的第一段代码是在Nor Flash中运行的,地址是0x00000000,然后执行一个BL跳转指令,跳转到什么地方了呢?我们看看反汇编后的代码:
                   bl cpu_init_crit /* we do sys-critical inits */
a3f00060: eb00001d bl a3f000dc cpu_init_crit>
可以清楚地看到实际上是跳转到0xa3f000dc处了,再看看0xa3f000dc处是什么:
a3f000dc :
...................................................
可见,0xa3f000dc处的确就是cpu_init_crit了。看起来好像没什么问题,但是注意一下,0xa3f000dc这个地址是在SDRAM中,现在刚上电,SDRAM中能有什么呢?肯定不会有我们的可执行程序。所以,这里肯定不是真正地跳转到0xa3f000dc这个地址上去了。
看来还是要回到我们的汇编程序中去。看看ARM Instruction Set中关于BL指令的相关描述:
Branch instructions contain a signed 2’s complement 24 bit offset. This is shifted left two bits, sign extended to 32 bits, and added to the PC. The instruction can therefore specify a branch of +/- 32Mbytes.
即,把offset中的值左移两位,在加上当前PC的值,就是跳转的目的地址。所以,BL是一个相对寻址,只能寻址当前PC指针的+/-32M的位置。
现在再来看看上面的BL指令到底跳转到什么地方去了。看看刚才的BL指令的指令码:eb00001d,说明它的offset是0x1d。按照上面的说法,先将0x1d左移两位,那么就是0x74,再加上当前的PC指针(从反汇编文件上看是0xa3f00060+8,但是实际上是0x60+8,因为是在Flash中),那么就是0xdc了,所以,实际上跳转的目的地还是在Flash中,而并没有到SDRAM中去!
在接下来的几个地方,还用到了BL指令,如bl lowlevel_init,情况都和这个类似。接下来,看看程序是从什么地方跳转到SDRAM中执行的。
在stage1结束的时候,程序使用如下语句跳入stage2(用C语言实现的部分):
ldr pc, _start_armboot
这句的反汇编代码:
                   ldr pc, _start_armboot
a3f000c0: e51ff004 ldr pc, [pc, #-4] ; a3f000c4 _start_armboot>
a3f000c4 _start_armboot>:
a3f000c4: a3f00988 mvnges r0, #2228224 ; 0x220000
即ldr pc, [pc, #-4],就是把pc-4处的值放入PC中,然后跳转到PC中执行。可以看到,现在PC的值应该是(0xc0+8),那么再减去4以后就是0xc4;同样可以看到0xc4处放的值是0xa3f00988,而这个地址确实就是RAM的地址,这样就真正跳转到RAM中执行了。
下面就是0xa3f00988处的反汇编代码:
a3f00988 start_armboot>:
a3f00988: e92d4070 stmdb {r4, r5, r6, lr}
......................................
正是我们的C语言反汇编的结果。
再来看看在S3C2410平台上从NAND启动的过程。
首先,从硬件上确定使用从NAND Flash启动。根据s3c2410的datasheet,从NAND Flash启动时,硬件会自动执行一下过程:
1. Reset is completed.
2. When the auto boot mode is enabled, the first 4 KBytes of NAND flash memory is copied onto Steppingstone 4-KB internal buffer.
3. The Steppingstone is mapped to nGCS0.
4. CPU starts to execute the boot code on the Steppingstone 4-KB internal buffer.
即,NAND Flash的前4KB内容被拷贝到一个叫Steppingstone的buffer中,然后Stppingstone被映射到nGCS0(地址就是0x00000000),然后CPU从地址0处开始执行程序。
所以,与前面的PXA270不同的地方只在执行程序前有个copy和映射的问题,这些都是硬件自动完成的,而不需要程序员干预。然后,后面的程序和在pxa270平台上执行都差不多了。
需要注意的是,在copy U-Boot的自身代码到SDRAM中时,pxa270平台和S3C2410平台上使用的方法是不一样的。但这不是我们今天讨论的重点。
综上所述,在U-Boot中,上电运行的第一段代码(汇编部分)是在Flash中运行,而C语言实现的stage2,则是在SDRAM中运行的。这其中涉及到了程序的跳转问题,汇编部分使用的相对跳转语句BL,只有到跳转到C语言的入口处,才使用了LDR PC语句,实现从Flash跳转到RAM中执行。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/57747/showart_1663744.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP