加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Eboot中应用NandFlash

发布时间:2020-12-15 06:17:55 所属栏目:百科 来源:网络整理
导读:注:本文nand flash 是基于K9F1G08U0B ? K9F1G08U0B的阵列结构图如下 ? 图1 Nand flash存储操作特点: 以页为单位进行读写,以block为单位进行擦除 ? 我们基于usb来download镜像的eboot来学习nandflash的应用,download的菜单一般如下所示: ? 图2 基于usb来

注:本文nand flash 是基于K9F1G08U0B

?

K9F1G08U0B的阵列结构图如下

?

图1

Nand flash存储操作特点:

以页为单位进行读写,以block为单位进行擦除

?

我们基于usb来download镜像的eboot来学习nandflash的应用,download的菜单一般如下所示:

?

图2

基于usb来download内核映像的步骤是:F -> 9 -> U,那么我们先来看F对应的功能

?

1.?????? 格式化nandflash

?

1.1?? ECC校验

?

nandflash的每一页有两区:main区和spare区,main区用于存储正常的数据,spare区用于存储其他附加信息,其中就包括ECC校验码。当我们在写入数据的时候,我们就计算这一页数据的ECC校验码,然后把校验码存储到spare区的特定位置中,在下次读取这一页数据的时候,同样我们也计算ECC校验码,然后与spare区中的ECC校验码比较,如果一致则说明读取的数据正确,如果不一致则不正确。ECC的算法较为复杂,好在s3c2440能够硬件产生ECC校验码,这样就省去了不少的麻烦事。s3c2443即可以产生main区的ECC校验码,也可以产生spare区的ECC校验码。因为K9F1G08U0B是8位IO口,因此s3c2443共产生4个字节的main区ECC码和2个字节的spare区ECC码。在这里我们规定,在每一页的spare区的第0个地址到第3个地址存储main区ECC,第4个地址和第5个地址存储spare区ECC。产生ECC校验码的过程为:在读取或写入哪个区的数据之前,先解锁该区的ECC,以便产生该区的ECC。在读取或写入完数据之后,再锁定该区的ECC,这样系统就会把产生的ECC码保存到相应的寄存器中。main区的ECC保存到NFMECC0/1中(因为K9F1G08U0B是8位IO口,因此这里只用到了NFMECC0),spare区的ECC保存到NFSECC中。对于读操作来说,我们还要继续读取spare区的相应地址内容,已得到上次写操作时所存储的main区和spare区的ECC,并把这些数据分别放入NFMECCD0/1和NFSECCD的相应位置中。最后我们就可以通过读取NFESTAT0/1(因为K9F1G08U0B是8位IO口,因此这里只用到了NFESTAT0)中的低4位来判断读取的数据是否正确,其中第0位和第1位为main区指示错误,第2位和第3位为spare区指示错误。

?

1.2 写sector的SectorInfo结构数据到spare field中。

对应于代码的实现部分如下所示:

?

图3

下面我们来看看这部分是如何格式化nand flash的,先看结构体SectorInfo的定义:

typedef struct _SectorInfo

{

??? DWORD dwReserved1;???? 2???????? // Reserved - used by FAL,为FAL保留的字节

??? BYTE? bOEMReserved;???? 3??????? // For use by OEM,为OEM保留的字节

??? BYTE? bBadBlock;? ?????? 1???? // Indicates if block is BAD,坏块标识

??? WORD? wReserved2;???? 4????????? // Reserved - used by FAL,为FAL保留的字节

???

}SectorInfo,*PSectorInfo;

对这个结构体的初始化代码如下:

?

图4

我们知道nandflash主要以page(页)为单位进行读写,以block(块)为单位进行擦除。每一页中又分为main区和spare区,main区用于正常数据的存储,spare区用于存储一些附加信息,如块好坏的标记、块的逻辑地址、页内数据的ECC校验和等。K9F1G08U0B中关于一页中main field和spare field的结构如下:

?

图5

下面接下来通过调用函数来把第0到第3个block标识为只读与保留的坏块,如下代码如下:

?

?

图6

这里主要是通过调用函数FMD_WriteSector来实现的,这个函数会调用FMD_LB_WriteSector()

主要部分如下所示:

?

图7

下面就来看看NAND_LB_WriteSectorInfo的函数体吧

?

图8

下面合适接着看NAND_LB_WriteSectorInfo函数的后部分

?

图9

下图是大页面的nandflash一页的结构图:

?

?

10

下图是K9F1G08U0B编程和读状态的操作时序图

?

图11

?

1.3?? 调用函数FMD_GetBlockStatus来获取存放eboot之后的所有的blcok的状态

?

该函数获得nandflash中某一个block的状态。参数为nandflash的block地址。由于nandflash中可能有坏块,所以针对nandflash,这个函数首先会检查当前块是否是坏块,这个一般通过读取当前block的第0个page和第1个page的带外数据。对于小page nandflash一般是读取第5个byte,对于大page nandflash一般读取第0个byte,如果不为0xff表示该块是坏块。当然,至于具体该读哪个byte,最好还是看一下所用nandflash的datasheet,确认一下,不同的厂家可能有所不同。如果发现该块是坏块,应该返回BLOCK_STATUS_BAD。如果不是坏块,需要读取这个块的起始扇区的扇区信息。如果读该扇区信息出错,应该返回BLOCK_STATUS_UNKNOWN,否则,判断独到的信息,返回相应结果。

?

具体是如何实现的呢,我们先来看函数的调用关系:

FMD_GetBlockStatus() -> FMD_LB_GetBlockStatus() -> FMD_LB_ReadSector() -> NAND_LB_ReadSectorInfo(),主要是通过NAND_LB_ReadSectorInfo函数来实现的,下面就来看看这个函数的内容:

?

图12

下图是读操作的时序图中的一部分:

?

图13

接着看NAND_LB_ReadSectorInfo函数的后半部分的实现:

?

图14

下面接着看ECC_CorrectData函数的实现

?

图15

下面我们回到FMD_LB_GetBlockStatus函数中来

?

图16

?

1.4?? 擦除eboot之后的非坏块

?

图17

下图是判读K9F1G08U0B某一块为坏块的根据和流程图

?

图18

下面来看看是如何擦除块的,函数的调用关系是:FMD_EraseBlock() -> FMD_LB_EraseBlock(),在看FMD_LB_EraseBlock函数之前,先来看看K9F1G08U0B对擦除块的操作时序图

?

图19

擦除是以块为单位进行的,因此在写地址周期是,只需写两个行周期,在擦除结束前还要判断是否擦除操作成功,FMD_LB_EraseBlock函数体如下:

?

图20

到此在下载NK.bin之前的格式化动作已经完成。

?

2. 在nandflash上建立BINFS分区,通过USB下载的NK.bin会保存在这个分区中。

代码入下图所示:

?

图21

这部分的内容见我的另一篇博文:

http://blog.csdn.net/LoongEmbedded/archive/2010/11/02/5981033.aspx

?

3.下载NK.bin

至于如何下载可以参考我的博文:WINCE6.0+S3C2443的启动过程系列博文

http://blog.csdn.net/LoongEmbedded/archive/2010/11/02/5981033.aspx

?

?

一些概念说明:

?

FAL及FMD做基本定义的說明如下:

?

FMD(FLASH Media Driver)可针对特定厂商的Flash作Driven、Read、Write、Erase等动作,实际上去对Flash做读写的操作。

?

FAL(FLASH Abstraction Layer):File System对Flash读写,必須透过此层操作。而此层则再更加FMD所提供的Interface再对Flash做读写。

?

NFSECC:Whenever data is read or written,the spare area ECC module generates ECC parity code on register

?

NFSECCD is for ECC in the spare area (Usually,the user will write the ECC value generated from main data area to Spare area,which value will be the same as NFMECC0/1) and which is generated from the main data area.

?

NFSECCD(nandflash的spare区ECC寄存器),NFMECCD0/1(nandflash的main区ECC寄存器),NFSECC(nandflash用于IO的ECC寄存器)。


?

参考链接:

http://blog.csdn.net/renpine/archive/2009/09/20/4572347.aspx

坏块http://apps.hi.baidu.com/share/detail/15657923

s3c2440对nandflash的操作(转载)http://www.360doc.com/showWeb/0/0/70026701.aspx



转自:LoongEmbedded的博客http://blog.csdn.net/loongembedded/article/details/6015302

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读