(二)识别NAND Flash Nor Flash

检测步骤:在启动的时候,将0x4000003c位置开始的四个字节清零,然后读取0x0000003c位置开始的四个字节。

        如果回读的结果为零,说明是Nand boot,否则就是Nor boot

 修改start.S

  第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           给全局变量赋值0
从第224 行左右开始,添加代码为:  
 判断当前代码位置,如果在内存,直接跳到stack_setup 
  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 */           获得 _start 的实际运行所在的地址值
  6. ldr r1, _TEXT_BASE  /* test if we run from flash or RAM */      获得地址_TEXT_BASE中所存放的数据
  7. cmp r0, r1  /* don't reloc during debug */            比较是否相等
  8. beq stack_setup                                    如果相等就跳到堆栈
  9. /***************** CHECK_CODE_POSITION*************************************/ 

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

  1. /***************** CHECK_BOOT_FLASH ******************************************/  
  2. ldr r1, =( (4<<28)|(3<<4)|(3<<2) )  /* address of Internal SRAM 0x4000003C*/ 内部SRAM的地址
  3. mov  r0, #0  /* r0 = 0 */  
  4. str r0, [r1]             写0
  5. mov  r1, #0x3c  /* address of 0x0000003C*/  被映射后的地址
  6. ldr r0, [r1]  
  7. cmp r0, #0 /* 判断0x0000003C所指向的4个字节是否被清0*/  比较
  8. bne relocate /* 没有被清0,就是在Nor Flash中启动,则跳到Nor Flash的重定向代码处relocate*/  
  9. /* recovery */  
  10. ldr r0, =(0xdeadbeef) /* 被清0,就是在Nand Flash中启动*/   恢复数据
  11. ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /* 恢复0x4000003C指向的4字节的数据0xdeadbeef*/  
  12. str r0, [r1]  
  13. /***************** CHECK_BOOT_FLASH ******************************************/
  在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               NFCONF基地址
  4.   
  5. #ifdef CONFIG_S3C2440  
  6. /* Offset */  
  7. #define oNFCONF 0x00                              配置
  8. #define oNFCONT 0x04                              控制
  9. #define oNFCMD  0x08                              指令
  10. #define oNFSTAT 0x20                              运行状态
  11.   
  12.     @ reset NAND  
  13.     mov  r1, #NAND_CTL_BASE  
  14.     ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )  CLE 和 ALE 持续值= HCLK × 3 TWRPH0 持续值= HCLK × ( 7 + 1 )
  15.     str r2, [r1, #oNFCONF]  TWRPH1 持续值= HCLK × ( 7 + 1 )  0:支持 256 字或 512 字节/页的 NAND Flash 存储器
  16.     ldr r2, [r1, #oNFCONF]  0=256 字/页     0=3 个地址周期     0=8 位总线

  17.     ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control  1:初始化 ECC 编码器/译码器
  18.     str r2, [r1, #oNFCONT]     0:强制 nFCE 为低(使能片选)  1:NAND Flash 控制器使能
  19.     ldr r2, [r1, #oNFCONT]  
  20.   
  21.     ldr r2, =(0x6)  @ RnB Clear 110 1:检测 RnB 传输    nCE 输出引脚的状态    0:NAND Flash 存储器忙 
  22.     str r2, [r1, #oNFSTAT]  
  23.     ldr r2, [r1, #oNFSTAT]  
  24.   
  25.     mov  r2, #0xff  @ RESET command   NAND Flash 存储器命令值  
  26.     strb r2, [r1, #oNFCMD]  
  27.       
  28.     mov  r3, #0  @ wait  
  29. nand1:  
  30.     add r3, r3, #0x1  
  31.     cmp r3, #0xa   循环10次
  32.     blt nand1     若上cmp结果为小于    跳转到nand1
  33.   
  34. nand2:  
  35.     ldr r2, [r1, #oNFSTAT] @ wait ready  无限循环等待,直到检测到NAND Flash变为繁忙状态
  36.     tst r2, #0x4     r2和100按位与
  37.     beq nand2       按位与的结果与0比较  若结果为0,跳转到nand2
  38.   
  39.     ldr r2, [r1, #oNFCONT]  
  40.     orr r2, r2, #0x2 @ Flash Memory Chip Disable  取消片选
  41.     str r2, [r1, #oNFCONT]  
  42.   
  43.     @ get read to call C functions (for nand_read())  
  44.     ldr sp, DW_STACK_START  @ setup stack pointer  //为C代码准备堆栈,DW_STACK_START定义在下面
  45.     mov  fp, #0  @ no previous frame, so fp=0  
  46.   
  47.     @ copy U-Boot to RAM  
  48.     ldr r0, =TEXT_BASE   //传递给C代码的第一个参数:u-boot在RAM中的起始地址
  49.     mov  r1, #0x0   //传递给C代码的第二个参数:Nand Flash的起始地址
  50.     mov  r2, #LENGTH_UBOOT   //传递给C代码的第三个参数:u-boot的长度大小(128k)
  51.     bl nand_read_ll   //此处调用C代码中读Nand的函数,现在还没有要自己编写实现
  52.     tst r0, #0x0                        测试r0是否为0
  53.     beq ok_nand_read                     如果r0=0, 开始测试是否搬移成功
  54.   
  55. bad_nand_read:  
  56. loop2:  
  57.     b  loop2  @ infinite loop     无限死循环
  58. ok_nand_read:  
  59.     @ verify      检查搬移后的数据,如果前4k完全相同,表示搬移成功
  60.     mov  r0, #0  
  61.     ldr r1, =TEXT_BASE  
  62.     mov  r2, #0x400 @ 4 bytes * 1024 = 4K-bytes  
  63. go_next:  
  64.     ldr r3, [r0], #4  
  65.     ldr r4, [r1], #4  
  66.     teq r3, r4  
  67.     bne notmatch       如果不相等,跳入死循环
  68.     subs  r2, r2, #4  
  69.     beq stack_setup    如果相等,跳入堆栈
  70.     bne go_next        如果不相等, 继续循环
  71.   
  72. notmatch:  
  73. loop3:  
  74.     b  loop3  @ infinite loop   无限死循环
  75. #endif  
  76. /***************** NAND_BOOT *************************************************/

 

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

 

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

  将下面的代码全部删掉:

  1. #ifndef CONFIG_SKIP_RELOCATE_UBOOT    删掉u-boot中nor Flash启动部分
  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.     ldmia  r0!, {r3-r10} /* copy from source address [r0] */  
  13.     stmia  r1!, {r3-r10} /* copy to target address [r1] */  
  14.     cmp r0, r2  /* until source end addreee [r2] */  
  15.     ble copy_loop  
  16. #endif /* CONFIG_SKIP_RELOCATE_UBOOT *

  第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 

 

posted @ 2015-01-08 10:52  来杯绿茶  阅读(412)  评论(0编辑  收藏  举报