一. 校验算法
ECC校验常用的算法有下列几种(下面参数以每512字节为单位)。
编码 | 纠错能力 | 额外空间 |
1-bit Haming | 1 bit | 3 |
4-bit BCH | 4 bit | 7 |
8-bit BCH | 8 bit | 14 |
16-bit BCH | 16 bit | 26 |
可使用下面公式评估Flash芯片每个Page的额外字节数,与不同算法的关系
NAND_OOBSIZE >= 2 + (NAND_PAGESIZE / ECC_SIZE) * ECC_BYTES
其中,OOBSIZE是芯片提供的额外空间,
PAGESIZE是芯片每页的字节数;
ECC_SIZE是ECC计算的字节数,通常使用512字节;
ECC_BYTES是每512字节需要额外的字节数(见上表)。
公式等号右边最开始的2字节,是因为每个OOB区最开始的2字节需要存放坏块标志,不能被占用。
二. 如何选择
选择最终产品使用哪种校验算法,可以根据Flash芯片OOB空间大小、Soc芯片硬件支持能力等因素。
耗用空间
根据上面的公式,以及前面举例的那个Flash芯片,可知可供选择的方案是1-bit Haming、4-bit BCH和8-bit BCH,但不可选择16-bit BCH。
如果选择1-bit Haming,ECC_BYTES=3,则OOB需要使用2+(2048/512)*3=14字节,OOB中还有50个字节可作他用;
选择8-bit BCH编码,ECC_BYTES=14,总共需要2+(2048/512)*14=58字节,OOB中还剩6个字节可供他用;
如果是16-bit BCH编码,算出的字节数是106字节,超过了OOB可以容纳的空间。
ECC硬件支持
有些Soc的GPMC控制器提供了ECC的硬件支持,例如AM335x芯片,就提供了BCH和Hamming码的计算。使用这类芯片就可选择Hardware实现,如果没有硬件支持,就只能选择Software实现,此时应该意识到,越是复杂的算法,软件计算耗用的资源也就越大。
三. ECC的配置
1. u-boot的配置
在u-boot中与NAND ECC相关的配置项大概有:
CONFIG_SYS_NAND_PAGE_SIZE
CONFIG_SYS_NAND_OOBSIZE
CONFIG_SYS_NAND_BLOCK_SIZE
CONFIG_SYS_NAND_ECCPOS
CONFIG_SYS_NAND_ECCSIZE
CONFIG_SYS_NAND_ECCBYTES
CONFIG_NAND_OMAP_ECCSCHEME
其中,SYS_NAND_PAGE_SIZE是Flash芯片每个Page的字节数,CONFIG_SYS_NAND_OOBSIZE是每个Page提供的额外空间(Spare)字节数,CONFIG_SYS_NAND_BLOCK_SIZE是每个块的字节数,应该是每Block的Page数 * PAGE_SIZE,这个字节数不包含额外空间。这三个数字可以从芯片资料上获得。
CONFIG_SYS_NAND_ECCPOS定义了一个数组,数组中的每个数字表示ECC校验码写入OOB空间的位置,没出现在数组中的位置是OOB的空闲区。
当下面任一配置项选择后,会使用到CONFIG_SYS_NAND_ECCPOS。
CONFIG_SPL_NAND_AM33XX_BCH,对于具备ELM支持能力的前提下,使能SPL-NAND驱动
CONFIG_SPL_NAND_SIMPLE,对于不具备ELM硬件支持的,提供软件ECC纠错支持
CONFIG_NAND_ATMEL,使用Atmel的Falsh芯片
CONFIG_SYS_NAND_ECCSIZE是每次计算ECC的字节数,一般缺省是512字节。以PageSize = 2048的芯片来说,就要进行4次ECC的计算。
CONFIG_SYS_NAND_ECCBYTES是每次计算ECC产生校验码的字节数,请参考表2-1。
CONFIG_NAND_OMAP_ECCSCHEME是OMAP芯片配置ECC scheme的配置项,其他芯片如何配置需要查看相关文档。
OMAP的ECC方案提供以下可选项
OMAP_ECC_HAM1_CODE_SW | 软件实现1-bit Hamming码 |
OMAP_ECC_HAM1_CODE_HW | GPMC硬件实现1-bit Hamming码 |
OMAP_ECC_BCH8_CODE_HW_DETECTION_SW | GPMC硬件实现8-bit BCH计算 软件实现错误侦测 |
OMAP_ECC_BCH8_CODE_HW | GPMC硬件实现8-bit BCH计算 ELM硬件实现错误侦测 |
OMAP_ECC_BCH16_CODE_HW | GPMC硬件实现8-bit BCH计算 ELM硬件实现错误侦测 |
2. Linux Kernel的配置
目前Linux对于资源的描述不再使用board.c的文件进行硬编码,而是通过DTS进行说明。例如我所使用的Flash芯片描述,在gpmc节点中。
&gpmc {
status = "okay";
......
nand@0,0 {
compatible = "ti,omap2-nand";
reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
......
ti,nand-ecc-opt = "default";
......
}
上面的DTS片段说明所选用的NAND使用ti的omap2-nand驱动,ti,nand-ecc-opt指定ECC算法策略。
omap2-nand驱动中,识别的ecc策略有
策略 |
|
default | OMAP_ECC_HAM1_CODE_SW |
sw | OMAP_ECC_HAM1_CODE_SW |
ham1 | OMAP_ECC_HAM1_CODE_HW |
hw | |
hw-romcode | |
bch4 | 有elm节点,则OMAP_ECC_BCH4_CODE_HW |
无elm节点,则OMAP_ECC_BCH4_CODE_HW_DETECTION_SW | |
bch8 | 有elm节点,则OMAP_ECC_BCH8_CODE_HW |
无elm节点,则OMAP_ECC_BCH8_CODE_HW_DETECTION_SW | |
bch16 | OMAP_ECC_BCH16_CODE_HW |
对于一片全新的NAND芯片,用户只要使用同一种ECC算法,就能正确写入和读取数据。
如果去读取一片已经写入内容的NAND芯片,就必须了解该芯片原先采用了哪种ECC算法,否则会出现ECC不正确
uncorrectable ECC errors
当然,如果不在意数据校验,也可以使用nand的raw读取操作,忽略OOB中的ECC数据。
下一篇文章接着介绍NAND芯片的访问操作。