NandFlash学习

来源:互联网 发布:悟空crm linux 编辑:程序博客网 时间:2024/06/06 16:58

NandFlash基础知识

1.Nand Flash的工艺上不能保证NAND的Memory Array在其生命周期中保持性能的可靠,所以,在NAND的生产中及使用过程中会产生坏块。对于生产中已经被检测出来的先天性坏块,厂商会在其oob特定位置标记坏块;而对于使用中产生的后天性坏块,它们将导致block erase(擦除后数据不为0xff)或者page program(写入数据不正确)失败,为保持与先天性坏块的一致性,应用程序同样需要在oob相同位置标记坏块,同时需要将坏块中其他好的page数据备份到另一个空的好块中。由于坏块很可能是对同一地址的过度操作导致,因此非常推荐在nand应用中实现均衡读写(wear-leveling)。

2.由于Nand Flash自身结构特性决定了它在使用过程中会出现位反转现象。为了保证数据的安全可靠,必须通过ecc(Error Checking and Correction)对数据进行校验,一般ecc结果就是放置在前面提到过的oob中的。一般位反转现象可以分成两种:一种是存储单元中数据是正确的,只是读取出来的位出现了反转,所以一般nand的读取过程中遇到ecc校验错误后需要对数据进行多次读取以确保不是读取过程中的干扰导致的位反转;当确认是存储单元物理上发生了位反转,可以通过ecc算法进行校正,当发现数据错误超出了算法校正能力,则认为这个块出现了实际数据错误,此时可以对数据进行取舍。如下图为K9GAG08U0E中的推荐读写流程,可以看到,位反转导致数据错误时未必说明这个块就是坏块,只有在写操作(erase / program)失败才是断定坏块的依据:
nand操作
每种容量的Nand对控制器的ECC要求不尽相同,在Datasheet可以找到,比如:
K9GAG08U0M 4bit/512bytes(每512B最多有4bit位反转)
K9F2G08U0A 1bit/512bytes(每512B最多有1bit位反转)
K9GAG08U0E 24bit/1024bytes(每1024B最多有24bit位反转)
每款MCU硬件支持的ECC在UserManual中可以找到,比如S3C6410的硬件ECC支持:
1bit/2048bytes
4bit/512bytes(产生7bytes ECC码)
8bit/512bytes(产生13bytes ECC码)
可以看到6410在硬件上并不支持K9GAG08U0E,可以猜到友善Tiny6410应该是通过软件的方式实现支持的。

U-Boot中对Nand的操作

uboot中常用的命令有:
nand erase 擦除nandflash
nand scrub 擦除nandflash,同时擦除oob,也就是通过scrub命令可以清除坏块标记
nand info 显示nandflash信息
nand bad 显示坏块
接下来介绍一下nand数据操作命令,Uboot的主要功能之一就是更新内核或者根文件系统,为了提前规划好Kernel与Rootfs的存储区域,Uboot中引入了linux上的mtd层,这样只需要统一kernel跟uboot中的分区表,内核就可以顺利找到nand上面的数据。由于引入了mtd分区,nand读写命令参数允许为分区名,命令在执行中自动从分区表上获得存取段的起始位置跟长度。
nand read/nand write
上面这个读写命令的缺点就是数据长度必须是块长度的整数倍,即需要块对齐。
为了操作方便,出现了不需要块边界对齐的命令,在很多地方可以看到他们有jffs和yaffs之分,这里需要指出,千万不要以为他们需要根据文件系统格式写入数据,在Uboot中完全没有必要引入文件系统,它需要做的就是将用户提供的数据镜像文件原原本本的拷贝到nand中就完成了。
先岔开话题,说说两个文件系统的区别,jffs是一种在norflash中用的比较多的文件系统,将jffs镜像烧录到nand时,需要对数据计算ECC校验码填入oob区;而yaffs是一种针对nand进行了优化的文件系统,它跟前者的主要区别就是yaffs镜像中已经包含了扩展区数据(除了包含ECC校验码之外,还包括一些坏块管理、平均读写、文件系统管理等的标志数据),烧写的时候直接写入到oob区即可。
对于读命令,可以统一使用:
nand read.i == nand read.e == nand read.jffs2
而对于写命令,针对上面提到的是否带oob数据的镜像,可以分别使用下面两种调用:(有的朋友问,为什么一般uboot里面都只有jffs跟yaffs两种方式的写入调用阿,那如果我想烧录ubifs还得自己修改源代码? 答:原因很简单,镜像就只分带oob数据的跟不带oob的,对于ubifs镜像(不带oob数据),可以调用nand write.i进行写入!!)
nand write.i ==nand write.e == nand write.jffs2
nand write.yaffs == nand write.yaffs1

文件系统镜像的生成命令

JFFS镜像
1.安装方法
下载安装mtd-util,编译工具包后可以得到mkfs.jffs2工具
或者直接在ubuntu环境下
apt-get install mtd-utils
2.使用方法
mkfs.jffs2 -s 0x1000 -e 0x40000 -p 0x500000 -d rootfs/ -o jffs2.img
具体命令参数可以通过man指令查看,这里不再详述。

YAFFS镜像
1.安装方法
下载yaffs源码,编译后,在utils目录下面可以找到mkyaffs2image工具
2.使用方法
mkyaffs2image dir image_file
需要注意,当使用不同型号的flash(页、块大小不同)时,需要找到mkyaffs2image.c文件,修改里面的chunk宏定义,重新生成mkyaffs2image

UBIFS镜像
1.安装方法
下载安装mtd-util,编译工具包后可以得到mkfs.ubifs工具
或者直接在ubuntu环境下
apt-get install mtd-utils
2.使用方法
mkfs.ubifs -r/tmp/rootfs-m 2048 -e 126976-c 992 -o ubifs.img(根据目录路径生成volume镜像)
ubinize -o ubi.img-m 2048 -p 128KiB-s 512 -O 2048 ubinize.cfg(可以将全部volume合并成为一个可以直接烧写到nand上面的镜像,这里只有一个卷)
最后这里提一下ubifs的相关知识,在MLC Nand上非常推荐使用这种文件系统,它为nand提供了非常优秀的坏块、损耗均衡等管理。这种文件系统最小物理分区是PEB,文件系统需要2片PEB用于存储卷表(volume table),1片PEB用于损耗平衡(wear-leaving),1片PEB用于atomic LEB change operation(不知道是干什么的),还有若干片PEB用于坏块管理(视具体情况),这些被文件系统预留的物理块对上层用户透明,所以用户可用的空间比实际物理空间要小一些。UBIFS并不占用oob区,因此在oob中仅保留ecc校验码。

U-Boot中的文件系统支持
前面提到对于U-Boot是完全没有必要实现文件系统支持的,当然如果实际有需要,那么可以可以参考UBoot源码common文件夹中的cmd_jffs2.c进行添加,一般UBoot都支持JFFS2文件系统,较新版本的好像都支持UBIFS,在实现文件系统支持后,就可以在terminal中通过命令对分区进行格式化或者读写文件了(还是直接使用镜像创建文件分区来的简单、暴力!)。

0 0
原创粉丝点击