首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 驱动开发 >

"200分啊"该怎么解决

2013-02-20 
200分啊!故障位置在u-boot-2013.01的arch/arm/cpu/arm1176/start.S//首先,在板的配置头文件中有如下定

"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>


这句不会有问题,因为ldr访问的目标地址是基于当前PC的一个偏移,能得到正确的地址"0x57e00e98",但它加载到'r0'的值却不会有任何的变化,仍然为‘0xc7e0004c’。不过,至少此时还没死,往下走。

c7e00da4:       e5903000        ldr     r3, [r0]
这句就不同了,ldr访问了一个不可访问的地址'0xc7e0004c',DRAM是挂到Bank6或Bank7的,两块空间都挂满物理地址也到不了0xc0000000,所以死了…………


嗯,
最后,我接触了u-boot的两个版本,2012.10及2013.01。两者代码虽有变化但执行流程流程是一样的。
我相信官方这么写应该是有其原因的,但我怎么想也想不通。因自己要用smdk6400这个板作为基础移植一个能在real6410上跑的u-boot,因此在此发问。
我这里是nand起动,算上nand_spl部分还是一样的。
nand_spl部分:
上电 => IROM => _start => 不执行relocate,开MMU被跳过,实际开不开都不影响 => 加载u-boot到RAM
非nand_spl,为什么又从_start开始,请参考nand_spl/nand_boot.c里"nand_boot"函数最后那华丽的一跳。
_start => 关MMU => 执行board_init_f(死掉)

请各位指正我分析的误点,如无误,请说下官方这么写的理由(猜的也行)。
[解决办法]
Uboot启动过程中,MMU和CACHE处于什么状态,为什么处于这个状态

先说 CACHE:数据cache必须关闭指令cache可以关闭也可以启动Bootloader主要是装载内核镜像,镜像数据必须真实写回SDRAM中,所以数据cache必须关闭,而对于指令cache,不存在强制性的规定,但在一般情况下,推荐关闭cache。 
关于MMU :似乎没什么太大影响。将飞凌提供的UBOOT源码关闭MMU时也能正常运行,只是要将地址修改成物理地址(似乎是用宏和偏移的方式控制的,不必手动修改,但还是注意一下吧)。
[解决办法]
board_init_f函数 
该函数为板级初始化的第一个函数,会对板子上很多硬件外设做初始化,其中最重要的为init_sequence数组,该数组里面包含了很多板级的硬件初始化函数,在board_init_f函数中会依次的调用该数组中的函数去初始化各个硬件,该数组如下:
init_fnc_t *init_sequence[] = {
#if defined(CONFIG_BOARD_EARLY_INIT_F)
         board_early_init_f,
#endif
#if defined(CONFIG_MPC85xx) 
[解决办法]
 defined(CONFIG_MPC86xx)
         probecpu,
#endif
...

希望对你能有帮助
[解决办法]
不懂
start.S
[解决办法]
ARM不懂,但是在powerpc上,上电后,MMU默认有一条是有效的,就是你最初的启动的4K空间,映射到你的启动设备比如nor flash上
[解决办法]
其实我是"200分啊"该怎么解决接分的。。。
[解决办法]
看一下你的连接脚本,在mmu没有打开之前,一些code_base是指定的,一定要正确。包括启动阶段和代码搬运阶段。包括mmu开启后的代码所在位置,都要对应好。

按我的理解, board_init_f应该是在mmu没有打开的时候调用的,怎么此时会是c7e00d88?
这个值可能和你的编译连接脚本有关,没有设置正确。 board_init_f是已经拷到内存中了?
或是是mmu打开后的值? boot中一些阶段后是可以打开mmu的。

[解决办法]
一般在boot mmu没有必要打开。os开始时是要打开的。
boot阶段也有打开的。 这主要看你的代码需要,简单代码不需要。
boot如果打开mmu,就要用好它,可能只映射一部分内存。

[解决办法]
也算我无聊"200分啊"该怎么解决

你是nand起动和非nand起动都实验了?

没做过该芯片的nand flash启动,但根据你的描述,我理解是这样:
分nand_spl.bin部分和u_boot.bin部分。
nand_spl.bin影射到0,也就是一般启动时候的地址。然后nand_spl.bin将u_boot.bin搬移到sdram中,接着跳转到u_boot.bin的start开始正常的启动。
你所说的 CONFIG_SYS_TEXT_BASE,目前看来是对nand_spl.bin起作用了,它也包含start.
而对于u_boot.bin中的start,也许也用到这个宏,或者有其他宏控制? 这个对u_boot.bin start影响目前倒是不大,可以认为它是地址无关,还没有跳转。 但根据你的反汇编,其地址明显是在sdram中了?你贴的是u_boot.bin中的start吧?接着跳转就出了问题。


nand_spl.bin搬uboot.bin到sdram的地址是多少? 谁控制的?  nand_spl.bin的start是谁控制?uboot.bin的start是谁控制? 他们一样吗?还有就是你上面帖的那个bl main, 符号main的地址是谁控制的? 
弄清了这些,估计就知道问题在哪里了。可能自己的configuration没作对,可能其build tree的机制不完善,得自己手动改写地址。

热点排行