故障位置在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>