Chinaunix首页 | 论坛 | 博客
  • 博客访问: 131033
  • 博文数量: 22
  • 博客积分: 949
  • 博客等级: 准尉
  • 技术积分: 266
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-10 22:31
文章分类

全部博文(22)

文章存档

2012年(1)

2011年(2)

2010年(19)

分类: 嵌入式

2011-03-15 19:56:16

前两天在俺们的EVB上加了点东西,增加了一下的BL语句进行初始化:
        BL       C2g_GsmStartZac
        LDR     pc, =INT_Initialize                  ;goto main in RAM
接着就出了一个奇怪的问题,使用RVDS,将PC置于代码烧录的其实地址0x40004,然后F5开跑,可以正常开跑。但是如果使用板子自带的boot进行启动,则跑不起来。
使用RVDS从boot开始跟踪,发现原来boot跳到主程序的过程中,跳入的地址为0x40040004,之所以这么做主要是为了和操作flash的代码进行统一,因为0-32K的Flash空间在系统运行的过程中被映射为内部IRAM,如果要操作这段Flash,则需要从0x4000000开始,通过地址绕转来巧妙的绕过这个问题。系统用了多年没出问题,其实是没在这个地方调用过IRAM里的函数。
本来,如果BL跳转的地址C2g_GsmStartZac,如果也是在Flash中,则不会有任何问题,反正地址都是绕转。另外,如果跳转到地址如果超出了BL的能力范围32M,编译器(链接器)本来也会想办法解决这个问题的,即将C2g_GsmStartZac的地址保存在Flash中的某个位置,然后通过LDR把地址加载到寄存器,再通过寄存器跳转。
出现前面说的问题的关键在于,这个地址正好位于0-32k的空间内,而且由于scatter loader文件中的链接地址又是0x40000开始的,导致编译器认为正好在BL跳转的32M范围内,直接编译成了通过偏移条状,即BL跳转是在当前PC的基础上加上偏移量来跳转的,因此就有了问题。
通过反汇编知道,使用0x40000进行链接,生成的代码如下:
        0x00040060:    fbff0269    i...    BLX      C2g_GsmStartZac  ; 0xa0e
根据文档《ARM Instruction》对BLX的介绍如下:
 其中的0-23位为有符号的偏移,指令fbff0269中对应的为0-22位为0x7f0269, 第23为1,表示负数,即负的0xFD97, 在左移两位为负的0x3F65c,加上H<<1, H为1, 运算结果为负的0x3F65A. 用PC值0x40060-3f65a=0xA06.和0xa0e差8,正好符合BLX指令下面的注释。但是当链接地址为0x40000开始,boot跳转却是到0x4000000时,此处的PC变成了0x4000060了,运算结果变成了0x4000060-3f65a=3FC0A06,访问的是绕转的Flash的内容,当然就有问题了。
实际上如果scatter loader写为0x4000000则,链接器处理的结果是这样的,使用了临时变量。
 
    0x40000060:    eb02bc1c    ....    BL       $Ven$AT$L$$C2g_GsmStartZac  ; 0x400af0d8
...........................
    $Ven$AT$L$$C2g_GsmStartZac
    $a
        0x400af0d8:    e59fc000    ....    LDR      r12,0x400af0e0
        0x400af0dc:    e12fff1c    ../.    BX       r12
    $d
    $f
        0x400af0e0:    00000a0f    ....    DCD    2575 ;即0xA0F, thumb
 
但是由于系统已经做好了,改变scatter loader的地址还要牵扯到MMU的配置,Flash的写入cache等诸多问题,最后的解决方法就是使用不会产生歧义的调用方法,即直接使用pc跳转
 
        mov     lr, pc
        LDR     pc, =C2g_GsmStartZac
        LDR     pc, =INT_Initialize                  ;goto main in RAM

这样在什么位置跳转都没有问题了,不过先得把pc保存到lr中(上面的第一句),不然调用后就回不来了。
 
阅读(3477) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~