特点
Nand flash存储结构为chip->(plane)->block->page>byte。
page分为数据区和oob(out of band),oob用于存放ecc码、标记坏块和文件系统备用等。
Nand flash的物理特性决定了每一个bit只能从1变为0,不能从0变为1。
Nand flash在出厂和使用过程中可能出现某些bit错误,所以采用了ecc的纠错和检错方法。
在读写过程中Nand flash状态寄存器返回错误或者发现多个bit发生不能纠错的错误,则可以标记该block为坏块,将该block的第一第二page的oob的相应byte置为非0xff,文件系统/操作系统需要管理坏块。
Nand flash的命令包括擦除、读、写,擦除针对block进行,将整个block全部置为1;读和写都针对page进行。因为每个bit只能从1到0,所以每次写之前,要进行擦除。基本三个阶段:命令->地址->数据,不同阶段根据引脚(片选、读\写使能、命令\地址锁存引脚等)决定。
对每个block中的page访问必须是顺序的,不能是随机的。
擦除和写次数是有寿命的,通常可达10万次。所以不能频繁对某个block进行擦除和写,所以软件需要将擦除和写平摊到每个block上,这种操作叫做负载均衡wear leveling。
Nand flash的IO是复用的,这样的好处就是pin少,可扩展性好。
ecc
ecc有软件和硬件之分。
对于硬件ecc来说,在写page的时候,硬件自动产生ecc,将其存入oob的某些byte。在读page的时候,硬件也自动产生一个ecc,并和oob比较,通过比较可以实现纠错和检错。
详见:
/course/3_program/c/c_js/0710/397316.html
Nand flash controller
Nand flash只是相当于cpu的一个外设,并不位于内存地址区。cpu内部有Nand flash controller与Nand flash打交道。
驱动程序
所谓Nand flash的驱动也就是对Nand flash controller编程(发送命令/写寄存器都是同样的意思)。驱动程序的结构大同小异,区别在于每家芯片的Nand flash controller的设计不同,所以对controller的编程的部分是不同的,还有不同的在于数据传输(比如,数据是拷贝或是DMA等)。
对于硬件ecc来说,基本的驱动包括下述功能:擦除block、读写page、ecc判断、坏块标识、读取Nand状态、等待Nand、复位Nand、初始化等;
初始化中要开辟驱动程序需要的memory,设置工作模式(page大小、block大小、时钟频率、ecc模式等),和对函数指针赋值:
驱动是分层的,以上是最底层的chip的驱动,是为了上层MTD服务的。
以读page为例:
chip->cmdfunc(MTD, NAND_CMD_READ0, 0x00, page);//先发读命令,由controller将读命令发给nand flash
chip->ecc.read_page(MTD, chip, buf);//然后读取数据(拷贝或者DMA方式),其中还有ecc校验
关于MTD的驱动架构详见:
《如何编写Linux下Nand Flash驱动》
MTD
linux下的设备分成block device和character device,flash两者都不是属于MTD(Memory Technology Device)。但这个只是指代的是原始的Nand flash和Nor flash芯片,衍生产品如SSD, MMC, eMMC, RS-MMC, SD, mini-SD, micro-SD, USB flash都属于block device。
block device和mtd device的区别如下:
像传统的文件系统,如FAT、ntfs、ext2、ext3等,都是建立在block device上的。MTD有自己的文件系统。
SSD, MMC, eMMC, RS-MMC, SD, mini-SD, micro-SD, USB flash这些设备里面的储存媒介当然还是flash,但是拆开它们还会发现一块MCU,它的firmware实现了FTL。所谓FTL是Flash Translation Layers,从软件上将flash“模拟”为block device了。
FTL的重要功能包括负载均衡、逻辑地址与物理地址映射、提供与block device相同的访问界面(512 bytes/sector)。FTL建立在MTD之上,传统的文件系统再建立在FTL之上。但每家厂家的FTL是不公开的,所以不知道好坏真的如何。遇到使用不好的FTL的U盘,可能马上出现“IO读写错误”了!
详见:
http://www.linux-/index.html
文件系统
常见的有JFFS2、YAFFS、TrueFFS文件系统都提供了坏块管理、负载均衡,ecc纠错检错等功能。
有UBIFS,UBIFS建立在UBI层上,UBI层建立在MTD上,而上述的两个文件系统是直接建立在MTD上的。
UBI要的工作就是实现更好的负载均衡和坏块管理,减轻文件系统的工作。
详见:
http://www.linux-/doc/ubifs.html
一般系统启动流程
Nor flash类似ram,地址线和数据线分开,一般位于内存地址区,支持代码片上执行。嵌入式芯片内部一般还有rom,从rom跳转到nor flash中执行代码,该代码称为bootloader,它初始化外设,串口、dram、nand flash等。之后bootloader把Nand flash中的main code拷贝到dram中去,接着跳转到main code入口。
当然启动有多种方式,main code较小的也有直接放在nor flash中,bootloader较大可能还会把自己也拷贝到dram中去。