NandFlash原理与启动详解






NandFlash原理与启动详解

一、Nandflash内部是怎么工作的:

  1片Nandflash=1设备  ;1设备=4096块;1块=32页;1页=528字节=数据大小(512字节)+oob块大小(16字节)


(oob用于Nandflash命令执行完成后设置状态)可以通过NAND Flash命令00h/01h/50h分别对前半部、后半部、OOB进行定位,通过NAND Flash内置的指针指向各自的首地址。

  存储操作特点有: 擦除操作的最小单位是块;NAND Flash芯片每一位只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前一定要将相应块擦除(擦除即是将相应块的位全部变为1);OOB部分的第6字节(即517字节)标志是否是坏块,值为FF时不是坏块,否则为坏块。除OOB第6字节外,通常至少把OOB的前3字节用来存放NAND Flash硬件ECC码。

(ECC:"Error Correcting Code" "错误检查纠正",带有奇偶校验的内存的主要功能。)

1.Nand  flash以page为单位进行读写,以block为单位进行擦除,没页分为main区和spare区,main区用于存放正常的数据,spare区用于存放一些附加信息

2.S3c2440 支持从Nand 启动是因为内部有一个叫做Steppingstone的SRAM buffer,当启动的时候,nand 的前4k的将会代码将被拷贝到steppingstone中执行,注意前4k代码是不会经过ECC校验的,所以必须确保这些代码的准确

3.对nand的操作都是通过使用命令来实现,有的操作只要一个命令就可以完成,而有的需要两个命令才能完成,下面是K9F1G08U0B的命令表:

4 Flash烧写程序原理及结构

  基本原理:将在SDRAM中的一段存储区域中的数据写到NAND Flash存储空间中。烧写程序在纵向上分三层完成。第一层:主烧写函数,将SDRAM中一段存储区域的数据写到NAND Flash存储空间中。第二层:该层提供对NAND Flash进行操作的页读、写及块擦除等函数。第三层:为第二层提供具体NAND Flash控制器中对特殊功能寄存器进行操作的核心函数,该层也是真正将数据在SDRAM和NAND Flash之间实现传送的函数。其中第二层为驱动程序的设计关键所在,下面对该层的读、写(又称编程)、擦除功能编码进行详细介绍。

 

 

nand flash 存储空间分布(图)

二、怎样从Nandflash拷贝并跳转到SDRAM的过程:

1.当S3C2440被配置成从Nand Flash启动时, S3C2440的Nand Flash控制器会在 S3C2440上电时自动把NandFlash上的前4K代码搬移到Boot Internal SRAM,然后系统从起始地址是0x0000_0000的Boot Internal SRAM启动,在这4K代码中我们必须完成CPU的核心配置,把NandFlash上的代码全部拷贝到SDRAM中去,然后跳转到SDRAM中去执行剩余的代码(进入操作系统等等);

 

                                                 (跳转到SDRAM的过程图

                                             (操作系统分布图)

2.这一步完成的是把NandFlash上的代码拷贝到SDRAM的过程:

(1)先判断是从nor启动还是从nand启动      

     ldr        r0,=BWSCON

             ldr        r0,[r0]

             ands     r0,r0, #6                 ;OM[1:0] != 0, NOR FLash boot

             bne      NORRoCopy          ;don't read nand flash

             adr       r0,ResetEntry         ;OM[1:0] == 0, NAND FLash boot // ADR 装载参照的地址=subr0,pc,#off_set;

             cmp      r0,#0                      ;if use Multi-ice,//JTAG调试时是直接下载到SDRAM中运行,不需要再从nand拷贝

             bne      InitRamZero            ;don't read nand flash for boot

注意哦,执行adr r0,ResetEntry后,r0 = PC - off_set,adr得到是相对地址而不是绝对地址。ResetEntry是整个程序的入口处,由链接器指定入口地址,如下图,ResetEntry=RO Base=0x3001_0000即|Image$$RO$$Base|。当程序在SDRAM中运行时,当前PC=0x3001_0000+off_set,r0=0x3001_0000,当程序在Boot Internal SRAM运行时,由于程序是从0x0000_0000开始运行的,所以当前PC=0x0000_0000+off_set,即r0=0x0000_0000。所以可以通过cmp r0,#0来判断程序是否运行在Boot Internal SRAM,如果是,则把NandFlash中的程序拷贝到SDRAM。

(2)从NandFlash拷贝程序到SDRAM

在这步中最让我困惑的是在SDRAM中从哪个地址开始存放从NandFlash拷过来的程序。

;===========================================================
;//将程序从nandflash拷贝到sdram
;===========================================================
nand_boot_beg
            bl         ClearSdram
            mov      r5,#NFCONF
            ;set timing value
            ldr        r0,        =(7<<12)|(7<<8)|(7<<4)
            str        r0,        [r5]
            ;enable control
            ldr        r0,=(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
            str        r0,[r5, #4]
           
            bl         ReadNandID
            mov      r6,#0
            ldr        r0,=0xecF1
            cmp      r5,        r0
            beq      %F1
;           ldr        r0,=0xecda
;           cmp      r5,r0
            mov      r6,#1                            ;Nandaddr(寻址周期 0:4 1:5)
1         
            bl         ReadNandStatus
           
            mov      r8,#0
           ldr        r9,=ResetEntry
            mov r10,#32                              ;+081010 feiling

上面代码中最关键的是这句:

 ldr        r9,=ResetEntry

其它都是一些NandFlash的相关设置与操作细节,先不管了。这据代码中用ldr来获得在SDRAM存放代码的起始地址,ldr将ResetEntry的绝对地址|Image$$RO$$Base|赋给了r9。也就是说,从NandFlash拷过来的代码放在了SDRAM中从|Image$$RO$$Base|开始的地址空间里。

3.CPU配置完了,程序和数据也都拷到SDRAM里了,该跳转到SDRAM里去做其他事情了,怎么知道是否跳转到SDRAM呢?这还是地址啊。我之前一直搞不清楚为什么一句ldr pc,=CEntry和bl Main就能从Boot Internal SRAM直接跳到SDRAM,原来在编译的时候,像ResetEntry和CEntry这些表示地址的标号都被赋于从|Image$$RO$$Base|开始之后的地址,只要|Image$$RO$$Base|大等于0x3000_0000,利用ldr取得绝对地址后赋给PC就能直接跳转到SDRAM里去了。我之前一直以为ResetEntry=0x0000_0000,而且分不清ldr和adr之间的差别,因此纠结了好久。  

ldr        pc,=CEntry                  ;goto compiler address
CEntry
            bl         Main                  ;Don t use main()because ......
            b          

三、启动代码和流程的分析

上述的汇编程序即是存放在NAND FLASH首页的启动代码,启动的流程如下:

(1)配置DMA控制器的4个寄存器,通道使能后,等待FLASH发出的搬运请求;

(2)配置NAND FLASH控制器的3个寄存器,选择适合的地址、时序参数与所用的FLASH芯片吻合;

(3)分别在r8~r11中放入程序需要的备用值;

(4)将需要在SDRAM中运行的4条指令搬入SDRAM 0x30000000处;

(5)执行Nop指令,Nop指令用于填充一页NANDFLASH中的剩余空间;

 

(6)执行在页末的指令,将PC指针指向SDRAM的0x30000000处;

(7)执行SDRAM中的指令,首先启动NANDFLASH的数据传输,将程序搬往SDRAM的0x30001000处。其次执行一个循环语句,等待第一页的程序搬完,之后将PC指针指向0x30001000处,启动程序从0x30001000处正式开始执行。



转载自:http://hi.baidu.com/sdcai/item/95589db474d77a9c1846971b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值