u-boot-2011.03在TQ2440上的移植(5)—实现Nand/Nor 双启动

1、在做u‐boot移植的时候,多数人使用的是Nand FLASH启动或Nor FLASH启动。这样u‐boot就只能在Nand FLASH或Nor FLASH。那么我们如何让我们的u‐boot在Nand FLASH或Nor FLASH都能使用。u-boot是系统启动前执行的一段程序,如果是放在Nandflash中的,那么u‐boot自己可以把自己搬移到内存中执行。

2、根据s3c2440数据手册得知:

对于Nand的操作和Nor的操作是完全不同的,选择Nor FLASH启动是将Nor FLASH映射到片选0上也就是0x0地址而选择Nand FLASH启动则是将CPU的片内RAM(4K)映射到0地址,通过Nand FLASH控制器操作Nand FLASH。所以:

a:如果是Nandflash启动,Nandflash在初始化之前是不能读写的,所以在2440内部有4k SRAM,在这里4KB空间里,可以完成Nandflash的初始化和搬运u-boot到RAM。

b:Norflash上电默认状态是读,所以可以直接搬运u-boot到RAM执行。

 

3、通过下图我们可以发现,我们可以通过判断BWSCON的第2位和地3位的值判断是Nor FLASH启动还是Nand FLASH启动。如果[2:1]是0 0 那么是Nandflash启动,反之则为Norflash启动。

4、修改第一阶段启动函数

vi arch/arm/cou/arm920t/start.S

Norflash和Nandflash拷贝uboot到RAM函数分别如下:

//初始化内存
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 bl cpu_init_crit
#endif

//nor/nand flash双启动判断
#define BWSCON 0x48000000
 ldr r0, =BWSCON
 ldr r0, [r0]
 ands r0, r0, #6  //判断BWSCON[2:1]是否为00,如果是,Z=1即跳转到nand_boot
 beq nand_boot

//系统从Norflash启动
relocate:    /* relocate U-Boot to RAM     */
 adr r0, _start  /* r0 <- current position of code   */
 ldr r1, _TEXT_BASE  /* test if we run from flash or RAM */
 cmp r0, r1   /* don't reloc during debug         */
 beq stack_setup

 ldr r2, _armboot_start
 ldr r3, _bss_start
 sub r2, r3, r2  /* r2 <- size of armboot            */
 add r2, r0, r2  /* r2 <- source end address         */

copy_loop:
 ldmia r0!, {r3-r10}  /* copy from source address [r0]    */
 stmia r1!, {r3-r10}  /* copy to   target address [r1]    */
 cmp r0, r2   /* until source end addreee [r2]    */
 ble copy_loop


//下面添加2440中u-boot从Nand Flash启动-----------------
nand_boot:

 mov r1, #NAND_CTL_BASE   //复位Nand Flash
 ldr r2, =( (0<<12)|(3<<8)|(0<<4)|(3<<2)|(1<<1) )
 str r2, [r1, #oNFCONF]   //设置配置寄存器的初始值,参考s3c2440手册
 ldr r2, [r1, #oNFCONF]

 ldr r2, =( (1<<4)|(1<<1)|(1<<0) )
 str r2, [r1, #oNFCONT]   //设置控制寄存器
 ldr r2, [r1, #oNFCONT]

 //ldr r2, =(0x01)           //RnB Clear
 //str r2, [r1, #oNFSTAT]
 //ldr r2, [r1, #oNFSTAT]
 
 mov r2, #0xff            //复位command
 strb r2, [r1, #oNFCMD]
 mov r3, #0               //等待

nand1:
 add r3, r3, #0x1
 cmp r3, #0xa
 blt nand1

nand2:
 ldr r2, [r1, #oNFSTAT]   //等待就绪
 tst r2, #0x4
 beq nand2

 ldr r2, [r1, #oNFCONT]
 orr r2, r2, #0x02         //取消片选
 str r2, [r1, #oNFCONT]


 //get read to call C functions (for nand_read())
 ldr sp, DW_STACK_START   //为C代码准备堆栈,DW_STACK_START定义在下面
 mov fp, #0

 //copy U-Boot to RAM
 ldr r0, =TEXT_BASE//传递给C代码的第一个参数:u-boot在RAM中的起始地址
 mov r1, #0x0      //传递给C代码的第二个参数:Nand Flash的起始地址
 mov r2, #0x30000  //传递给C代码的第三个参数:u-boot的长度大小(192k)
 bl nand_read_ll   //此处调用C代码中读Nand的函数,/board/samsung/smdk2440/nand_read.c
 tst r0, #0x0
 beq ok_nand_read

 bad_nand_read:
 loop2: b loop2    //infinite loop
 
ok_nand_read:

 //检查搬移后的数据,如果前4k完全相同,表示搬移成功
 mov r0, #0
 ldr r1, =TEXT_BASE
 mov r2, #0x1000           //4 bytes * 1024 = 4K-bytes

go_next:
 ldr r3, [r0], #4
 ldr r4, [r1], #4
 teq r3, r4
    bne notmatch
 
    subs r2, r2, #4
    beq stack_setup
    bne go_next

notmatch:
    loop3:
 b loop3           //infinite loop

4、make即可

你可能感兴趣的:(c,Flash,Go,FP)