在2004年的时候本人采用Nand Flash作为存储器对收费站的客运记录进行记录保存。当时采用的是三星的Nand Flash芯片,通过Philips(后来的NXP)的LPC2000系列ARM控制器实现对Nand Flash的操作。Nand Flash采用的是标准IO接口,所以开发操作Flash的Firmware并不是十分困难的事情。由于信息记录采用的是日志方式,因此,不会涉及到SSD遇到的写平衡和写放大等问题。我开发的第一块Nand Flash数据存储卡如下图所示:
Nor Flash具有较高的读性能,但是写性能极差(在写入的时候需要擦除,擦除的时候需要对存储单元进行清1操作,所以擦除时间比较长),并且容量较小,因此,常被用作程序存储器,采用标准存储器总线接口。现在,很多嵌入式开发中经常采用Nor Flash保存U-Boot、Linux Kernel以及Initrd。Nand Flash是另外一类Flash,其写性能要远高于Nor Flash,并且集成度很高,特别当Intel引入MLC技术之后,Nand Flash容量增长迅速,具有很高的单芯片容量。Nand Flash的大容量特性以及不错的读写性能正好满足了大容量存储的需求,可以替代磁盘应用,因此,Nand Flash采用IO接口方式。
Nand Flash单芯片容量这几年增长的非常迅速,在2008年的时候,一个Intel SSD(X25)的容量只能达到64GB。但是,今天单芯片容量已经达到了1Tb(128GB),单芯片容量超过了几年前的一个SSD固态硬盘。这种容量的剧增,主要还是存储领域对Nand Flash容量需求导致的。通常,Nand Flash内部分成若干Block、Page和LUN,一个LUN的结构如下图所示:
这是Micron的Nand Flash(MT29E512G08CUCAB型号)内部结构,一个Page页大小为8KB(有的 Flash page页大小为4KB),一个block块拥有256页,一个LUN有4096个块。因此,一个LUN的总大小为8GB。一个芯片可以封装多个LUN,如果封装了8个LUN,那么整个Nand Flash芯片容量可以达到64GB。
从上图可以看出,每个Nand Flash芯片提供了多组读写接口(传统的Nand Flash芯片只拥有一个读写接口),每个Target拥有一个读写接口,每个接口都可以采用同步或者异步操作方式。读写操作可以针对一个Page页或者单字节进行操作;写操作前需要将整个Block块擦除,然后才能进行写入操作。Nand Flash的问题也就在于Block擦除,如果上层软件想要更新Block块中的一个Page页,那么首先需要擦除整个Block,然后才能写入最新的Page数据,这就是典型的写放大问题。另外,每个Block的擦除次数是有限的,所以这种频繁的擦除操作会导致Nand Flash块损坏。为了解决这个问题,需要在Nand Flash控制器中的Firmware做很多工作。
Nand Flash控制器内部结构不是十分复杂,其芯片(JMicro)内部结构如下图所示:
其内部核心模块分为:多路Flash控制器、SATA控制器、内存控制器以及CPU处理器。如上图所示的JMF605拥有四个Flash接口控制器,因此,可以与四片传统的Nand Flash接口芯片相连(采用JMF605构成的SSD如下图所示)。如果采用Micron的MT29E512G08CUCAB芯片,JMF605只能连接一片MT29E512。
从硬件的角度看,采用现有的控制器和Nand Flash构建SSD并不是什么问题,其最大的问题还是在于如何解决Nand Flash与生俱来的问题。所以,很多SSD厂商的技术核心也就在于Firmware的算法,该算法采用了很多存储虚拟化的方法。