Chinaunix首页 | 论坛 | 博客
  • 博客访问: 152700
  • 博文数量: 22
  • 博客积分: 1456
  • 博客等级: 上尉
  • 技术积分: 252
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-25 00:08
个人简介

ddd

文章存档

2011年(1)

2010年(21)

我的朋友

分类: 嵌入式

2010-06-06 21:10:16

Nand Flash 和 Nor Flash 双启动方法探究
 
 
在三星的S3C2440的技术手册上有写着:
S3C2440有三种启动方式,可以通过OM[1:0]管脚进行选择
(1)OM[1:0]=00,从Nand Flash启动;
(2)OM[1:0]=01,从16位宽的ROM启动;
(3)OM[1:0]=10,从32位宽的ROM启动;
 
“The data bus of BANK0 (nGCS0) should be configured with a width as one of 16-bit and 32-bit ones. Because the BANK0 works as the booting ROM bank (map to 0x0000_0000), the bus width of BANK0 should be determined before the first ROM access, which will depend on the logic level of OM[1:0] at Reset.”
 

 OM1 (Operating Mode 1)

 OM0 (Operating Mode 0)

 Booting ROM Data width

 0

     Nand Flash Mode

0

1

          16-bit

1

          32-bit

1

1

         Test Mode

 
 
同时我们可以看到: 总线宽度和等待控制寄存器
BUS WIDTH & WAIT CONTROL REGISTER
 
BWSCON   0x48000000
 
 BWSCON  Bit  Description Initial state 
 DW0  [2:1]  Indicate data bus width for bank 0 (read only).
01 = 16-bit,   10 = 32-bit
  The states are selected by OM[1:0] pins
 --------------
 
在系统重启时会扫描BWSCON的状态,而BWSCON的其他位的初始状态都是0,只有DW0(BWSCON[2:1])的值由OM[1:0]来决定,通过上面的2个图我们可以发现,我们可以通过判断BWSCON的第2位、第3位   {DW0(BWSCON[2:1])}的值,判断是Nor flash启动还是Nand Flash启动。可以启动代码之前添加如下代码,来判断是Nor flash启动还是Nand Flash启动。

# define BWSCON   0x48000000
        ldr r0,=BWSCON
        ldr r0,[r0]
        and r0,r0,#6
        cmp  r0, #0 
        bne  relocate
         

/****************************/
     //nand_boot
  //Nand 搬移代码
/****************************/

 /****************************/
    relocate:
       //nor_boot
      //Nor 搬移代码
/****************************/

有了上面这段代码,就可以实现双启动了,只要再适当的添加对应的功能我们的uboot就完成了。


结合Tekkaman  Ninja的启动代码可以有:

1)判断当前代码位置,如果在内存,直接跳到stack_setup

/*********** CHECK_CODE_POSITION *******************/

  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

/********** CHECK_CODE_POSITION ******************/

2)如果不是在代码当前位置不再内存中,就判断启动的FlashNand 或者Nor

/***************** CHECK_BOOT_FLASH *********************/

  修改部分:(将Tekkaman  Ninja代码修改

# define BWSCON  0x48000000
        ldr r0,=BWSCON
        ldr r0,[r0]
        ands r0,r0,#6
        cmp  r0, #0 
        bne  relocate
 

  /***************** CHECK_BOOT_FLASH ***********************/

 

3)如果判断是在Nand Flash中启动的话,那么nand  Flash搬移代码如下:

 

定义u-bootnand flash中存放的长度为#define LENGTH_UBOOT 0x60000,可以方便修改u-boot因为裁剪和增添大小的改变而占的长度。

 

// copy U-Boot to RAM  form   Nand Flash

 

/*********** NAND_BOOT **********************************/

 

#define LENGTH_UBOOT 0x60000

#define NAND_CTL_BASE 0x4E000000

 

#ifdef CONFIG_S3C2440

/* Offset */

#define oNFCONF 0x00

#define oNFCONT 0x04

#define oNFCMD 0x08

#define oNFSTAT 0x20

 

  @ reset NAND

  mov      r1, #NAND_CTL_BASE

  ldr  r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )

  str  r2, [r1, #oNFCONF]

  ldr  r2, [r1, #oNFCONF]

 

  ldr  r2, =( (1<<4)|(0<<1)|(1<<0) )      @ Active low CE Control

  str  r2, [r1, #oNFCONT]

  ldr  r2, [r1, #oNFCONT]

 

  ldr  r2, =(0x6)      @ RnB Clear

  str  r2, [r1, #oNFSTAT]

  ldr  r2, [r1, #oNFSTAT]

 

  mov      r2, #0xff @ RESET command

  strb       r2, [r1, #oNFCMD]

 

  mov      r3, #0      @ wait

nand1:

  add       r3, r3, #0x1

  cmp      r3, #0xa

  blt  nand1

 

nand2:

  ldr  r2, [r1, #oNFSTAT]       @ wait ready

  tst  r2, #0x4

  beq       nand2

 

 

  ldr  r2, [r1, #oNFCONT]

  orr r2, r2, #0x2    @ Flash Memory Chip Disable

  str  r2, [r1, #oNFCONT]

 

  @ get read to call C functions (for nand_read())

  ldr  sp, DW_STACK_START      @ setup stack pointer

  mov      fp, #0      @ no previous frame, so fp=0

 

  @ copy U-Boot to RAM

  ldr  r0, =TEXT_BASE

  mov      r1, #0x0

  mov      r2, #LENGTH_UBOOT

  bl   nand_read_ll

  tst  r0, #0x0

  beq       ok_nand_read

 

bad_nand_read:

loop2:

  b    loop2      @ infinite loop

ok_nand_read:

  @ verify

  mov      r0, #0

  ldr  r1, =TEXT_BASE

  mov      r2, #0x400      @ 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

#endif

 

#ifdef      CONFIG_S3C2410

 

/* Offset */

#define oNFCONF 0x00

#define oNFCMD 0x04

#define oNFSTAT 0x10

 

  @ reset NAND

  mov      r1, #NAND_CTL_BASE

  ldr  r2, =0xf830    @ initial value

  str  r2, [r1, #oNFCONF]

  ldr  r2, [r1, #oNFCONF]

  bic r2, r2, #0x800 @ enable chip

  str  r2, [r1, #oNFCONF]

  mov      r2, #0xff        @ RESET command

  strb       r2, [r1, #oNFCMD]

 

 

  mov      r3, #0      @ wait

nand1:

  add       r3, r3, #0x1

  cmp      r3, #0xa

  blt  nand1

 

nand2:

  ldr  r2, [r1, #oNFSTAT]       @ wait ready

  tst  r2, #0x1

  beq       nand2

 

  ldr  r2, [r1, #oNFCONF]

  orr r2, r2, #0x800 @ disable chip

  str  r2, [r1, #oNFCONF]

 

  @ get read to call C functions (for nand_read())

  ldr  sp, DW_STACK_START      @ setup stack pointer

  mov      fp, #0      @ no previous frame, so fp=0

 

  @ copy U-Boot to RAM

  ldr  r0, =TEXT_BASE

  mov      r1, #0x0

  mov      r2, #LENGTH_UBOOT

  bl   nand_read_ll

  tst  r0, #0x0

  beq       ok_nand_read

 

bad_nand_read:

loop2:

  b    loop2      @ infinite loop

 

 

ok_nand_read:

  @ verify

  mov      r0, #0

  ldr  r1, =TEXT_BASE

  mov      r2, #0x400      @ 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

 

#endif

/*************** NAND_BOOT *******************************/

(4)  如果判断是在Nor  Flash中启动的话,那么nor  Flash搬移代码如下

 

// copy U-Boot to RAM  form   Nor  Flash

 

//#ifndef CONFIG_SKIP_RELOCATE_UBOOT

/***************** NOR_BOOT ****************************/

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

/***************** NOR_BOOT ****************************/

//#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

  
 
Tekkaman  Ninja也写过关于识别启动Flash的方法:在U-boot下实现自动识别启动Flash的原理(针对S3C24x0)。大家可以去看看。在此感谢Tekkaman  Ninja提供的启动代码。
 
 
 
 
 
 
阅读(3737) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~