当前位置: 代码迷 >> 驱动开发 >> "200分啊"该怎么解决
  详细解决方案

"200分啊"该怎么解决

热度:9269   发布时间:2013-02-26 00:00:00.0
"200分啊!"
故障位置在u-boot-2013.01的"arch/arm/cpu/arm1176/start.S"

//首先,在板的配置头文件中有如下定义:
#if !defined(CONFIG_NAND_SPL) && (CONFIG_SYS_TEXT_BASE >= 0xc0000000)
#define CONFIG_ENABLE_MMU
#endif

//其次,对start.S前部分的执行流程作简要描述:
_start:  b reset
reset:
     //更改CPU模式为SVC32
cpu_init_crit:
     //主要行为,关MMU
bl lowleve_init
bl _main
    //以前没有_main函数,而是执行一个名为board_init_f的函数,现此函数的调用位置_main函数
relocate_code:
    //与主题无关
copy_loop:
    //与主题无关
fixloop:
   //与主题无关
fixabs:
  //与主题无关
fixrel:
  //与主题无关
fixnext:
  //与主题无关
enable_mmu:
  //开MMU



由上面的宏定义可知,只有当”CONFIG_SYS_TEXT_BASE >= 0xc0000000“才会开MMU,对于arm11这决对是个虚拟地址。
在Makefile中ld使用了参数-Ttext $(CONFIG_SYS_TEXT_BASE),也就是说最后生成的u-boot的入口地址是个虚拟地址。

好,问题来了:
入口_start进来 => 关MMU => 执行board_init_f(死掉)
虚拟地址        物理地址    为什么死呢?下面用反汇编分析


c7e0004c <_bss_end_ofs>:
c7e0004c:       0006d2a0        andeq   sp, r6, r0, lsr #5
......
c7e00d88 <board_init_f>:
c7e00d88:       e92d44f0        push    {r4, r5, r6, r7, sl, lr}
c7e00d8c:       e3a01000        mov     r1, #0
c7e00d90:       e3a02080        mov     r2, #128        ; 0x80
c7e00d94:       e1a00008        mov     r0, r8
c7e00d98:       eb00746f        bl      c7e1df5c <memset>
#下面这句把内存单元'0xc7e00e98'的内存加载到‘r0’.
c7e00d9c:       e59f00f4        ldr     r0, [pc, #244]  ; c7e00e98 <board_init_f+0x110>
c7e00da0:       e3a01010        mov     r1, #16
#对照下面‘0xc7e00e98’处的内容后,可知此时'r0'的值为‘0xc7e0004c’.
#如果不出意外的话,执行完这句后,‘r3’的值应该为‘0x0006d2a0’。
c7e00da4:       e5903000        ldr     r3, [r0]
c7e00da8:       e59f00ec        ldr     r0, [pc, #236]  ; c7e00e9c <board_init_f+0x114>
......
c7e00e98:       c7e0004c        strbgt  r0, [r0, ip, asr #32]!
c7e00e9c:       c7e27d6d        strbgt  r7, [r2, sp, ror #26]!


好,咋一看木有问题,对,确实没有问题啊!
不过,大家似乎忘记了,此时MMU的状态!
此时的MMU还处于关闭状态,因此,此时的pc值应该是以"0x57e"开头的。

c7e00d9c:       e59f00f4        ldr     r0, [pc, #244]  ; c7e00e98 <board_init_f+0x110>
  相关解决方案