uboot移植之支持板子nand启动

之前介绍的uboot源码中smdk2410开发板的重定位方式只支持板子从nand启动,可以从重定位的copy_loop看出:

uboot移植之支持板子nand启动

 

 

 重定位时cpu直接从flash中读数据,写入目的地址(位于SDRAM),这样的方式只能用在norflash中启动的代码上,nandflash中的内容不能像这样简单地通过指令读写。

smdk2410的重定位方式支持把代码重定位到任何地址上,但这种方式有两个缺点:

1、重定位代码复杂

2、会增加需要移植的uboot的体积,因为需要增加rel.dyn段,记录 保存着全局变量地址的LABEL的地址

现在采用直接指定uboot链接地址的方法,重写重定位代码,使板子能从nandflash启动。

需要做如下工作:

1、去掉 "-pie"选项,链接时不生成rel.dyn段

  arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 注释掉这行

2、board/samsung/smdk2440目录中增加init.c文件,里面加入对nandflash读写的代码:

uboot移植之支持板子nand启动

 

 

 并在makefile中添加init.o目标文件:

uboot移植之支持板子nand启动

 

 

 3、修改链接脚本: 把start.S, init.c, lowlevel.S等文件放在最前面

./arch/arm/cpu/u-boot.lds:

uboot移植之支持板子nand启动

 

 

 这是因为s3c2440如果设置为nand启动,上电后会nandflash中的前4k内容读到cpu内部ram执行,要保证我们自己实现的nand的读写、初始化函数、重定位等代码位于前4k才能被正确执行。

4、修改start.S

  ldr    sp, =(CONFIG_SYS_INIT_SP_ADDR)    /*sp = 30000f80*/
    bic    sp, sp, #7 /* 8-byte alignment for ABI compliance */  //由于nandflash是c函数,在调用c函数之前要先设置栈

    bl nand_init_ll            //调用nand初始化函数

    mov r0, #0            //设置r0,r1,r2,传参给copy_code_to_sdram
    //ldr r1, =_start
    ldr r1, _TEXT_BASE
    ldr r2, _bss_start_ofs
    
    bl copy_code_to_sdram   //重定位代码c函数
    bl clear_bss      //清除bss段

    ldr pc, =call_board_init_f
/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
    ldr    r0,=0x00000000
    bl    board_init_f
    
    /*board_init_f 的返回值(unsigned int)id的值存在r0里,传参给board_init_r用*/
    ldr r1, _TEXT_BASE
    /*调用第二阶段代码*/
    bl board_init_r

5、在board.c文件中,在board_init_f函数末尾把relocate_code(addr_sp, id, addr)注释掉

  因为之前在start.S中调用了重定位函数,这边就不需要再重定位了。

6、之前smdk2410在SDRAM中给uboot留了一段空间用于保存重定位之后的uboot代码,现在保存uboot的地址由自己定义,为0x33f000000,需要把borad.c中的

board_init_f函数里addr变量赋值为0x33f000000。

 

重新编译uboot,从nandflash启动会打印出uboot信息,说明nandflash启动成功:

uboot移植之支持板子nand启动

 

上一篇:剑指 Offer 12. 矩阵中的路径


下一篇:c语言三子棋游戏(每天一个装杯小技巧,源码在末尾)