首页 > 代码库 > Uboot(二)支持NAND Flash和NOR Flash

Uboot(二)支持NAND Flash和NOR Flash

 四、自动识别从NAND Flash启动还是从Nor flash启动 

      原理:在启动的时候,用程序将0x40000000~0x40001000中的某些位置清零,然后回读0x00000000~0x00001000中的相应位置,

                           为零说明是NAND boot如果是原来的数据就是Nor boot

      判断完后如果是NAND boot,还要恢复被改动的数据,再进入自拷贝阶段。

    选择了在start.S文件开头,全局中断向量之后第57行的变量:.balignl 16,0xdeadbeef 。
    理由如下:
    (1)他是非零数,而且数据是确定的:0xdeadbeef
    (2)他的位置是固定的:0x0000003c(0x4000003c)
    (3)他在检测程序之前,不会影响程序的向下运行
    (4)他不属于程序,他是一个程序中的魔数(Magic Number),用魔数来检测也比较合理
    所以最后的检测步骤是:在启动的时候,将0x4000003c位置开始的四个字节清零,然后读取0x0000003c位置开始的四个字节。如果回读的结果为零,说明是Nand boot,否则就是Nor boot。如果是Nand boot,必须要复原清零的数据。原因是:在Nand boot过后,会核对内部SRAM中的4K程序,和从Nand中拷贝到SDRAM的前4K程序是否一致,如果不一致会进入死循。

1、 第90行左右添加一个Flash启动标志,从Nand启动时将其设置为0,从Nor启动时将其设置为1

  1. .globl _bss_start  
  2. _bss_start:  
  3. .word __bss_start  
  4. .globl _bss_end  
  5. _bss_end:  
  6. .word _end  
  7. .globl bBootFrmNORFlash  
  8. bBootFrmNORFlash:  
  9. .word 0  

 2、判断当前代码位置,如果在内存,直接跳到stack_setup   第224行左右

  1. #ifndef CONFIG_SKIP_LOWLEVEL_INIT  
  2. bl cpu_init_crit  
  3. #endif  
  4. /***************** CHECK_CODE_POSITION***************************************/  
  5. adr r0, _start /* r0 <- current position of code */  
  6. 11  
  7. ldr r1, _TEXT_BASE /* test if we run from flash or RAM */  
  8. cmp r0, r1 /* don‘t reloc during debug */  
  9. beq stack_setup  
  10. /***************** CHECK_CODE_POSITION*************************************/

 3、如果代码当前位置不在内存中,就判断启动方式为Nand Flash或者Nor Flash

  1. /***************** CHECK_BOOT_FLASH ******************************************/  
  2. ldr r1, =( (4<<28)|(3<<4)|(3<<2) )    /* address of Internal SRAM 0x4000003C*/ 
  3. mov r0, #0          /* r0 = 0 */  
  4. str r0, [r1] 
  5.  
  6. mov r1, #0x3c       /* address of 0x0000003C*/  
  7. ldr r0, [r1]  
  8. cmp r0, #0          /*判断0x0000003C所指向的4个字节是否被清0*/  
  9. bne relocate        /*没有被清0,就是在Nor Flash中启动,则跳到Nor Flash的重定向代码处relocate*/  

  10. /* recovery */  
  11. ldr r0, =(0xdeadbeef) /*被清0,就是在Nand Flash中启动*/  
  12. ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /*恢复0x4000003C指向的4字节的数据0xdeadbeef*/  
  13. str r0, [r1]  
  14. /***************** CHECK_BOOT_FLASH ******************************************/ 

 

4、在Nand Flash中启动的话,那么Nand Flash搬移代码如下:

 

     定义u-boot在Nand flash中存放的长度为#define LENGTH_UBOOT 0x100000,可以方便修改u-boot因为裁剪和增添大小的改变而占的长度。
  1. /***************** NAND_BOOT *************************************************/  
  2. #define LENGTH_UBOOT 0x100000  
  3. #define NAND_CTL_BASE 0x4E000000  

  4. #ifdef CONFIG_S3C2440  
  5. /* Offset */  
  6. #define oNFCONF 0x00  
  7. #define oNFCONT 0x04  
  8. #define oNFCMD 0x08  
  9. #define oNFSTAT 0x20  

  10. @ reset NAND  

  11. mov r1, #NAND_CTL_BASE  
  12. ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )  
  13. str r2, [r1, #oNFCONF]  
  14. ldr r2, [r1, #oNFCONF] 
  15.  
  16. ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control  
  17. str r2, [r1, #oNFCONT]  
  18. ldr r2, [r1, #oNFCONT]  

  19. ldr r2, =(0x6) @ RnB Clear  
  20. str r2, [r1, #oNFSTAT]  
  21. ldr r2, [r1, #oNFSTAT]  

  22. mov r2, #0xff @ RESET command  
  23. strb r2, [r1, #oNFCMD]  

  24. mov r3, #0 @ wait  
  25. nand1:  
  26. add r3, r3, #0x1  
  27. cmp r3, #0xa  
  28. blt nand1  

  29. nand2:  
  30. ldr r2, [r1, #oNFSTAT] @ wait ready  
  31. tst r2, #0x4  
  32. beq nand2  

  33. ldr r2, [r1, #oNFCONT]  
  34. orr r2, r2, #0x2 @ Flash Memory Chip Disable  
  35. str r2, [r1, #oNFCONT]  

  36. @ get read to call C functions (for nand_read())  
  37. ldr sp, DW_STACK_START @ setup stack pointer  
  38. mov fp, #0 @ no previous frame, so fp=0  
  39.  
  40. @ copy U-Boot to RAM  
  41. ldr r0, =TEXT_BASE  
  42. mov r1, #0x0  
  43. mov r2, #LENGTH_UBOOT  
  44. bl nand_read_ll  
  45. tst r0, #0x0  
  46. beq ok_nand_read  

  47. bad_nand_read:  
  48. loop2:  
  49. b loop2 @ infinite loop  
  50. ok_nand_read:  
  51. @ verify  
  52. mov r0, #0  
  53. ldr r1, =TEXT_BASE  
  54. mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes  
  55. go_next:  
  56. ldr r3, [r0], #4  
  57. ldr r4, [r1], #4  
  58. teq r3, r4  
  59. bne notmatch  
  60. subs r2, r2, #4  
  61. beq stack_setup  
  62. bne go_next  

  63. notmatch:  
  64. loop3:  
  65. b loop3 @ infinite loop  
  66. #endif  
  67. /***************** NAND_BOOT *************************************************/ 

 5、在Nor Flash中启动的话,那么Nor Flash搬移代码如下:

  1. /***************** NOR_BOOT *************************************************/  
  2. relocate: /* relocate U-Boot to RAM */  
  3. /*********** CHECK_FOR_MAGIC_NUMBER***************/  
  4.  
  5. ldr r1, =(0xdeadbeef)  
  6. cmp r0, r1  
  7. bne loop3  
  8. /*********** CHECK_FOR_MAGIC_NUMBER***************/  
  9. adr r0, _start /* r0 <- current position of code */  
  10. ldr r1, _TEXT_BASE /* test if we run from flash or RAM */  
  11. ldr r2, _armboot_start  
  12. ldr r3, _bss_start  
  13. sub r2, r3, r2 /* r2 <- size of armboot */  
  14. add r2, r0, r2 /* r2 <- source end address */  
  15. copy_loop:  
  16. ldmia r0!, {r3-r10} /* copy from source address [r0] */  
  17. stmia r1!, {r3-r10} /* copy to target address [r1] */  
  18. cmp r0, r2 /* until source end addreee [r2] */  
  19. ble copy_loop  
  20. SetBootFlag:  
  21. ldr r0, =bBootFrmNORFlash  
  22. mov r1, #1 /*从Nor启动,将标志设置为1*/  
  23. str r1, [r0]  
  24. /***************** NOR_BOOT *************************************************/
6、将下面的代码全部删掉:

 

  1. #ifndef CONFIG_SKIP_RELOCATE_UBOOT  
  2. relocate: /* relocate U-Boot to RAM */  
  3. adr r0, _start /* r0 <- current position of code */  
  4. ldr r1, _TEXT_BASE /* test if we run from flash or RAM */  
  5. cmp r0, r1 /* don‘t reloc during debug */  
  6. beq stack_setup  
  7. ldr r2, _armboot_start  
  8. ldr r3, _bss_start  
  9. sub r2, r3, r2 /* r2 <- size of armboot */  
  10. add r2, r0, r2 /* r2 <- source end address */  
  11. copy_loop:  
  12. 15  
  13. ldmia r0!, {r3-r10} /* copy from source address [r0] */  
  14. stmia r1!, {r3-r10} /* copy to target address [r1] */  
  15. cmp r0, r2 /* until source end addreee [r2] */  
  16. ble copy_loop  
  17. #endif /* CONFIG_SKIP_RELOCATE_UBOOT *

 7、第378行左右添加代码:

  1. _start_armboot: .word start_armboot  
  2. #define STACK_BASE 0x33f00000  
  3. #define STACK_SIZE 0x10000  
  4. .align 2  
  5. DW_STACK_START: .word STACK_BASE+STACK_SIZE-4  

 

Uboot(二)支持NAND Flash和NOR Flash