文档库

最新最全的文档下载
当前位置:文档库 > Nand Flash 介绍及高通nand flash驱动

Nand Flash 介绍及高通nand flash驱动

Nand Flash 介绍及高通nand flash驱动

1. Nand Flash 相关概念

1.1 NOR flash与nand flash

1) Nor flash 写速度要比Nand flash 慢得多,Nor flash的读速度比Nand flash快得多。

2.)Nor flash 可以挂上CPU 芯片的地址线,不需要额外的sdram 就可直接在Nor flash 中直接运行,而Nand flash 需要代码搬运到Ram中运行,所以需要Boot loader,需要额外的sdram 的开销。

3)Nandflash需要做badblock检测和ecc校验;每个page中需有一块区域标识坏块信息,而 Nor flash 没有badblock 和ecc 校验的概念。

4)Nand flash最小的program单位为page,而Nor flash 可以对bit进行

Nand Flash 介绍及高通nand flash驱动

1.2 什么是SLC和MLC

SLC,Single Level Cell:单个存储单元,只存储一位数据,表示成1或0.

对于数据的表示,单个存储单元中内部所存储电荷的电压,和某个特定的阈值电压Vth,相比,如果大于此Vth值,就是表示1,反之,小于Vth,就表示0.

MLC,Multi Level Cell:与SLC相对应,就是单个存储单元,可以存储多个位,比如2位,4位等。其实现机制,就是,通过控制内部电荷的多少,分成多个阈值,通过控制里面的电荷多少,而达到我们所需要的存储成不同的数据。比如,假设输入电压是Vin=4V那么,可以设计出2的2次方=4个阈值, 1/4 的Vin=1V,2/4的Vin=2V,3/4的Vin=3V,Vin=4V,分别表示2位数据00,01,10,11。对于写入数据,就是充电,通过控制内部的电荷的多少,对应表示不同的数据。

另,nand flash:

页大小是512+16=528的称为small page

页大小是2048+64=2112的称为large page

1.3 Nand flash的组成结构

Nand Flash 介绍及高通nand flash驱动

图2 Nand flash 物理存储单元的阵列组织结构

NAND Flash 的数据是以bit 的方式保存在memory cell,一般来说,一个cell 中只能存储一个bit。这些cell 以8 个或者16 个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device 的位宽。这些Line 会再组成Page。

如上图flash的结构,每个page包含2012Byte,每64 个page 形成一个Block, 8192个block形成整个flash。 page=2012Byte=2048(Main

Area)+64byte(Spare Area)

2 .Nand flash 命令及寻址方式:

Nand flash的操作,一般都用通用的命令。如下图表示nand flash操作的相关命令。

Nand Flash 介绍及高通nand flash驱动

图3 Nand flash 相关操作命令

2.1 Nand Flash 寻址方式

Block是NAND Flash中最大的操作单元,擦除就是按照block为单位完成的而编程/读取是按照page为单位完成的。

所以,按照这样的组织方式可以形成所谓的三类地址:

-Block Address 块地址

-Page Address 页地址

-Column Address 页内偏移地址

Nand Flash 介绍及高通nand flash驱动

图4 Nand flash的地址周期组成

NAND Flash的地址表示为:

Block Address|Page Address in block|Column Address

地址传送顺序是Column Address,Page Address,Block Address。

由于地址只能在I/O[7:0]上传递,因此,必须采用移位的方式进行。

Column address就是表示页内的地址

如上flash的读看,此nand flash地址周期共有4个,2个列(Column)周期,2个行(Row)周期。而对于对应地,我们可以看出,实际上,列地址A0~A10,就是页内地址,地址范围是从0到2047,而对出的A11,理论上可以表示2048~4095,但是实际上,我们最多也只用到了2048~2011,用于表示页内的oob区域,其大小是64字节

Row address 表示页号即页地址:

A12~A30,称作页号,页的号码,可以定位到具体是哪一个页。而其中,A18~A30,表示对应的块号,即属于哪个块。由于共有8192块故用13位表示

A12~A17,表示块中的那一页,由于1块有64个页故用6位表示。

2.2 操作过程的解释

下面以nand flash的读操作来解释nand flash的工作过程及相关时序。

Nand Flash 介绍及高通nand flash驱动

图5 Nand flash 读操作时序

对于读操作的,上面图中标出来的,1-6个阶段,具体是什么含义。

(1)操作准备阶段:此处是读(Read)操作,所以,先发一个图5中读命令的第一个阶段的0x00,表示,让硬件先准备一下,接下来的操作是读。

(2)发送两个周期的列地址。也就是页内地址,表示,我要从一个页的什么位

置开始读取数据。

(3)接下来再传入三个行地址。对应的也就是页号。

(4)然后再发一个读操作的第二个周期的命令0x30。接下来,就是硬件内部自

己的事情了。

(5)Nand Flash内部硬件逻辑,负责去按照你的要求,根据传入的地址,找到哪个块中的哪个页,然后把整个这一页的数据,都一点点搬运到页缓存中

去。而在此期间,你所能做的事,也就只需要去读取状态寄存器,看看对

应的位的值,也就是R/B#那一位,是1还是0,0的话,就表示,系统是busy,仍在”忙“(着读取数据),如果是1,就说系统活干完了,忙清

了,已经把整个页的数据都搬运到页缓存里去了,你可以接下来读取

你要的数据了。

(6)通过Nand Flash的控制器中的数据寄存器中写入你要读取多少个字节(by te)/字(word),然后就可以去Nand Flash的控制器的FIFO中,一点点读取你要的数据了。至此,整个Nand Flash的读操作就完成了。

3 Nand flash 坏块及ECC校验

Nand flash 中都会存在坏块,管理坏块是nand flash的重要工作,如果有文件系统,则文件系统会管理flash的坏块,如果没有则我们需要自己管理flash 的坏块。

3.1 bad block及其标记

在一个block里有1个或多个bit的状态不能稳定的编程,就没法使用它。如果一个block(128KByte)有一个Bit是坏的,那么整个block放弃使用。一般整个nand flash的最大坏块率为2%。

编程或擦除操作之后,重要的是读状态寄存器,因为它确认是否成功地完成了编程或擦除操作。如果操作失败,要把该区块标记为损坏且不能再使用。以前已编写进去的数据要从损坏的区块中搬出,转移到新的(好的)存储块之中。管理器件的软件负责映射坏块并由好的存储块取而代之。初始化软件仅仅需要扫描所有区块确定以确定哪个为坏,然后建一个坏块表供将来参考。

bad block有2种,一种是initial bad block,另一种是runtime bad block。所谓initial bad block就是出厂时就是坏块的

1) initial bad block:initial bad block的标记是保证坏块的前2个page 里的spare area里的第一个字节的内容不会是0xFF。已page为2K为例,如果前2个page其中一个的2048地址(从0开始计数,以后都是这种计数方式)上的数据(就是spare area的第一个字节)是0xFF,那么这个块不是initial bad block。值得注意的一点是bad block的标记会被erase掉成0xFF,所以有可能会误被认为是good block。所以在对每一个block earse之前一定要判断是不

是bad block,否则将bad block的标志erase了,以后使用的时候会误被当作good block,从而有可能带来数据损失。

2) runtime bad block:对于runtime的bad block,就是使用中出现的bad block,可以从erase或program后对成功与否的判断来决定这个block是否变成bad block,如果是的话则标记。一般标记的法则和initial bad block一样,在前两个page的spare area的第一个byte上写非0xFF值,

在msm7625平台linux侧nand flash驱动中标记坏块函数msm_nand_block_markbad;其方法就是把块的第一页全部写为0.

3.2 Nand flash ECC

NAND需要ECC以确保数据完整性。NAND闪存的每一个页面上都包括额外的存储空间,它就是64个字节的空闲区(每512字节的扇区有16字节)(以2K page flash为例)。该区能存储ECC代码及其逻辑到物理块映射之类的信息。ECC能在硬件或软件中执行,但是,硬件执行有明显的性能优势。在编程操作期间,ECC 单元根据扇区中存储的数据来计算误码校正代码。数据区的ECC代码然后被分别写入到各自的空闲区。当数据被读出时,ECC代码也被读出;运用反操作可以核查读出的数据是否正确。

能校正的错误的数量取决于所用算法的校正强度。在硬件或软件中包含ECC,就提供了强大的系统级解决方案。最简单的硬件实现方案是采用简单的汉明(Simple Hamming)码,但是,只能校正单一位错误。瑞德索罗门(Reed-Solomon)码提供更为强大的纠错,并被目前的控制器广为采用。此外,BCH码由于比瑞德索罗门方法的效率高,应用也日益普及。

4nand flash page layout

nand flash中包含有main区和spare(oob)区,main区存储的为我们需要的数据区。

而spare区存储的为ECC等数据。一般文件系统中会用到spare区域,比如把逻辑页与物理页的映射关系存储在spare区中。

Main区的ECC校验保存在SPARE区,SPARE空间比较大的NAND会对MAIN的ECC校验再进行ECC校验,相当于是spare区的一部分数据也进行了ECC,这部分存储位置因为很小,所以坏的可能性很小。

所以对应nand flash的校验可以main区数据校验,也可以main与spare 一起校验,还有一种就是不需要校验也就是raw方式操作。所以也有不同的page layout。

Nand Flash 介绍及高通nand flash驱动

Nand Flash 介绍及高通nand flash驱动

5 高通平台nand flash驱动

高通平台已对nand flash驱动做的比较完善,实际需要做的工作不多。相关驱

动详细代码在/drvier/flash下:

同统一对flash操作的接口在nand_flash.c中的flash_nand_ops中,

struct fs_device_data flash_nand_ops =

{

/* Device dispatch table - public interface */

flash_nand_device_name, /* Device Name */

flash_nand_maker_id, /* Maker Identification

*/

flash_nand_device_id, /* Device Identification

*/

flash_nand_block_count, /* Block Count */

flash_nand_block_size, /* Pages in block */

flash_nand_page_size, /* Page Size */

flash_nand_total_page_size, /* Total Page Size */

flash_nand_device_type, /* Device Type */

flash_nand_device_width, /* Device Width */

/* As these are device dependent these function ptrs are overwritten

* by the device probed */

flash_nand_op_not_initialized, /* Bad Block Check */

flash_nand_mark_block_bad, /* Mark Bad Block */

flash_nand_write_page, /* Write Page */

flash_nand_erase_block, /* Erase Block */

0, /* Read Pointer */

flash_nand_read_page, /* Read Page */

flash_nand_is_page_erased, /* Is Page Erased

*/

0, /* Partial Write */

0, /* Begin Erase Block */

. . .

. . .

. . .

};

Flash的操作函数flash_nand_ops为通用的一个flash 操作的接口。根据

flash的的不同会设置具体的flash操作函数。我们用到的对flash的底层操作

函数在flash_nand_ctlr_a_device_probe函数中定义。具体的操作函数在

flashi_nand_ctlr_d.c中

priv->ctlr.write_page =

flash_nand_ctlr_a_write_page;

priv->ctlr.read_page =

flash_nand_ctlr_a_read_page;

priv->ctlr.erase_block =

flash_nand_ctlr_a_erase_block;

priv->ctlr.is_page_erased =

flash_nand_ctlr_a_is_page_erased;

priv->ctlr.is_block_erased =

flash_nand_ctlr_a_is_block_erased;

priv->ctlr.mark_block_bad =

flash_nand_ctlr_a_mark_block_bad;

priv->ctlr.read_spare_bytes =

flash_nand_ctlr_a_read_spare_bytes;

priv->ctlr.set_ecc_state =

flash_nand_ctlr_a_set_ecc_state;

priv->ctlr.read_mpages =

flash_nand_ctlr_a_read_mpages;

priv->ctlr.read_spare_udata =

flash_nand_ctlr_a_read_spare_udata;

priv->ctlr.read_page_and_udata =

flash_nand_ctlr_a_read_page_and_udata;

priv->ctlr.mark_block_bad =

flash_nand_ctlr_a_mark_block_bad;

priv->ctlr.reconfigure = NULL;

我们做改动的主要是针对具体flash的型号参数信息,配置一些系统参数,

比如\AMSS\products\7625\secboot\cfg_data\ebi2目录下有ebi2.cfg文件,

该文件就是对bootloader配置flash的相关参数,;还有在

flash_nand_samsung.c的flash_device_config_data samsung_devices_array[]

数组中添加我们需要用的flash的信息等。

6 Linux 侧nand flash驱动

6.1 linux中 nand flash 的驱动结构

MSM7625中与nand flash底层相关的代码有msm_nand.c common.c nand_partitions.c。其中主要的底层访问接口在msm_nand.c中。

由于7225平台为双CPU,在linux侧也需要nand flash的驱动接口。

对应7225平台,flash的分区信息在arm9侧(高通amss侧),所以在linux 侧第一步需要获取系统的分区信息,获取那几个分区是给linux侧用的。

Nand flash 在linux中的device结构,如下:

Nand Flash 介绍及高通nand flash驱动

Nand Flash 介绍及高通nand flash驱动

msm_nand_data的相关分区信息会在系统启动时候调用static int get_nand_partitions(void)函数,来填充。该函数获取arm9侧的分区信息,已分区名字作为判断是否属于arm11侧分区。

后面的动作和标准linux设备驱动的结构差不多,首先probe等

对应的驱动函数为msm_nand.c中

Nand Flash 介绍及高通nand flash驱动

msm_nand_probe :Probe函数中会读取flash的ID,判断我们用的ID是否支持,如果匹配不到对应的flash ID号,则返回出错。读取ID后会初始化相关flash控制器相关寄存器设置,并且关联底层flash操作函数,后把获取的分区信息,注册到系统。

Nand Flash 介绍及高通nand flash驱动

Nand Flash 介绍及高通nand flash驱动

Linux侧在对flash相关控制器设置时候,需要与高通侧的flash设置一致,否则会导致出现两边读写不匹配现象。

6.2 linux访问nand flash的接口

Nand flash注册成功后每个分区会有2个访问的设备节点,如/dev/mtd0 /dev/mtdblock0 表示一个物理分区。

1)字符设备形式访问分区。

以linux侧字符设备形式来访问,是通过/dev/mtd0 节点来访问的。

访问相关接口在mtdchar.c文件中,

Nand Flash 介绍及高通nand flash驱动

这样范围nand flash 可以像访问其他字符设备一样的访问方式。可以对flash 读,写,擦除,坏块检查等操作。

由于以字符设备形式访问,没有管理坏块的机制,所以在已mtdchar接口做

flash操作时候就需要自己管理坏块。

高通中的升级操作,就是用到mtdchar 字符设备来对flash操作的。

2)以块设备来访问nand flash。

一般我们系统对nand flash的操作都是用块设备形式来访问的。都会挂载一个文件系统来对nand falsh操作。块设备访问的接口相关代码有mtdblock.c mtdblock_ro.c等。

Nand Flash 介绍及高通nand flash驱动

Nand flash访问结构层次

挂载文件系统时候会对nand flash的分区进行扫描,坏块检查等动作。文件系统会管理坏块。例如我们用的是yaffs2文件系统。挂载命令如下:Muont –t yaffs2 /dev/mtdblock0 /mnt/flash

当挂载成功后我们就可以在/mnt/flash下直接进行cp拷贝文件,建立目录等操作。

管理nand flash的文件系统有很多,一般有jffs2, yaffs, cramfs, romfs, ramdisk, 等。常用的是jffs2,和yaffs.其中jffs2主要是应用与nor flash。Yaffs文件系统主要应用与nand flash。具体对文件系统的了解可以参考相关文件系统资料