nand flash坏块管理OOB,BBT,ECC
0.NAND的操作管理方式 ?????NAND FLASH的管理方式:以三星FLASH为例,一片Nand flash为一个设备(device),1 (Device) = xxxx (Blocks),1 (Block) = xxxx (Pages),1(Page)?=528 (Bytes) = 数据块大小(512Bytes) + OOB 块大小(16Bytes,除OOB第六字节外,通常至少把OOB的前3个字节存放Nand Flash硬件ECC码)。 ????? 关于OOB区,是每个Page都有的。Page大小是512字节的NAND每页分配16字节的OOB;如果NAND物理上是2K的Page,则每个Page分配64字节的OOB。如下图: ????????????? 以HYNIX为例,图中黑体的是实际探测到的NAND,是个2G bit(256M)的NAND。PgSize是2K字节,PgsPBlk表示每个BLOCK包含64页,那么每个BLOCK占用的字节数是 64X2K=128K字节;该NAND包好2048个BLOCK,那么可以算出NAND占用的字节数是2048X128K=256M,与实际相符。需要注 意的是SprSize就是OOB大小,也恰好是2K页所用的64字节。 ?1.为什么会出现坏块 2.坏块的分类 3.坏块管理 ????? 可以用BBT:bad block table,即坏块表来进行管理。各家对nand的坏块管理方法都有差异。比如专门用nand做存储的,会把bbt放到block0,因为第0块一定是好 的块。但是如果nand本身被用来boot,那么第0块就要存放程序,不能放bbt了。?有的把bbt放到最后一块,当然,这一块坚决不能为坏块。?bbt的大小跟nand大小有关,nand越大,需要的bbt也就越大。 ??????需要注意的是:OOB是每个页都有的数据,里面存的有ECC(当然不仅仅);而BBT是一个FLASH才有一个;针对每个BLOCK的坏块识别则是该块第一页spare area的第六个字节。? ????? ECC:?NAND Flash出错的时候一般不会造成整个Block或是Page不能读取或是全部出错,而是整个Page(例如512Bytes)中只有一个或几个bit出 错。一般使用一种比较专用的校验——ECC。ECC能纠正单比特错误和检测双比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的 错误不保证能检测。 ???? (3)为什么好块用0xff来标记?因为Nand Flash的擦除即是将相应块的位全部变为1,写操作时只能把芯片每一位(bit)只能从1变为0,而不能从0变为1。0XFF这个值就是标识擦除成功,是好块。 ===================================================
? =============================================================== ? MTD的坏块管理(一)-快速了解MTD的坏块管理
1?人收藏此文章,?收藏此文章?发表于2个月前,已有
65?次阅读 共
0?个评论?
1?人收藏此文章
由 于NAND Flash的现有工艺不能保证NAND的Memory Array在其生命周期中保持性能的可靠,因此在NAND芯片出厂的时候,厂家只能保证block 0不是坏块,对于其它block,则均有可能存在坏块,而且NAND芯片在使用的过程中也很容易产生坏块。因此,我们在读写NAND FLASH 的时候,需要检测坏块,同时还需在NAND驱动中加入坏块管理的功能。?? 在struct nand_chip中与bbt相关的结构体如下: struct?nand_chip?{? }; bbt指向 一块在nand_default_bbt函数中分配的内存,若options中没有定义NAND_USE_FLASH_BBT,MTD就直接在bbt指向 的内存中建立bbt,否则就会先从NAND芯片中查找bbt是否存在,若存在,就把bbt的内容读出来并保存到bbt指向的内存中,若不存在,则在bbt 指向的内存中建立bbt,最后把它写入到NAND芯片中去。?? bbt_td、bbt_md和badblock_pattern的结构体类型定义如下: struct?nand_bbt_descr?{? options:bad block table或者bad block的选项,可用的选择以及各选项具体表示什么含义,可以参考<linux/mtd/nand.h>。?? ****?****
MTD坏块管理(二)-内核获取Nandflash的参数过程
1?人收藏此文章,?133?次阅读 共
MTD坏块管理机制中,起着核心作用的数据结构是nand_chip,在此以TCC8900-Linux中MTD的坏块管理为例作一次介绍。 MTD在Linux内核中同样以模块的形式被启用,TCC_MTD_IO_Init()函数完成了nand_chip初始化、mtd_info初始注册, 坏块表的管理机制建立等工作。 nand_chip在TCC_MTD_IO_Init函数中的实例名称是this,mtd_info 的实例名称为TCC_mtd,这里有一个比较巧妙的处理方法: TCC_mtd=kmalloc(sizeof(struct mtd_info)+sizeof(struct nand_chip),GFP_KERNEL); this=(struct nand_chip*)(&TCC_mtd[1]); 在以后的操作中,只需得知TCC_mtd即可找到对应的nan_chip实例。 获得必要的信息后(包括nand_chip方法的绑定),流程进入nand_scan(TCC_mtd,1). nand_scan(struct mdt_info *mtd,int maxchips); 调用nand_scan_ident(mtd,maxchips)和nand_scan_tail(mtd); nand_scan_ident(...)调用了一个很重要的函数:nand_get_flash_type(...) *从nand_get_flash_type(...)函数中可以看出每个nandflash前几个字节所代表的意思都是约定好了的: 第一个字节:制造商ID 第二个字节:设备ID 第三个字节:MLC 数据 第四个字节:extid (比较总要) 其中设备ID是访问nand_flash_ids表的参照,该表在drivers/mtd/nand/nand_ids.c中定义 Linux内核在nand_flash_ids参照表中,通过匹配上述设备ID来查找nandflash的详细信息, nand_flash_ids中的举例如下: struct nand_flash_dev nand_flash_ids[]={ ...... {"NAND 16MiB 1,8V 8-bit",? 0x33,512,16,0x4000,0}, {"NAND 16MiB 3,3V 8-bit",? 0x73,8V 16-bit",?0x43,NAND_BUSWIDTH_16},3V 16-bit",?0x53,29); font-family:Verdana; font-size:12px">} 466 struct nand_flash_dev { 467 ? ? char *name; 468 ? ? int id; 469 ? ? unsigned long pagesize; 470 ? ? unsigned long chipsize; 471 ? ? unsigned long erasesize; ? ? 472 ? ? unsigned long options; ? ? ? 473 };? 值得一提的是,MTD子系统会把从nand_flash_ids表中找到的chipsize复制给mtd->size,这在有些应用中显得不合适, 在有些方案中,并不是把nandflash的所有存储空间都划分为MTD分区,Telechips的TCC89XX方案就是这样,4G的nandflash 上,可以划分任意大小的MTD分区,错误的mtd->size的后果非常严重,造成系统启动慢,整个MTD的坏块管理机制瘫痪等等。 随后,nand_get_flash_type通过extid计算出了以下信息: mtd可写区大小:mtd->writesize=1024<<(extid&0x03); 这里可以看成1024*(1*2的(extid&0x03)次方), mtdoob区大小:extid>>=2;mtd->oobsize = (8<<(extid&0x1))*(mtd->writesize>>9); 每512字节对应(8*2的(extid&0x1)次方)字节oob数据 mtd擦写块大小:extid>>=2;mtd->erasesize=(64*1024)<<(extid&0x03); nand数据宽度 :extid>>=2;busw=(extid&0x01)?NAND_BUSEWIDTH_16:0; 现在大多为8位数据宽度 可以看出第四个字节extid的意义: 高|0 ? ?| ?0 ? ? ? ?| ? 00 ? ? ? ?| 0 ? | 0 ? ? ? ? | ?00 ? ? ? ? ? |低 ?? |无用|数据宽度|擦写块算阶|无用|oob算阶| ?可写区算阶| nand_get_flash_type(...)还确立了nandflash中的坏块标记在oob信息中的位置: if(mtd->writesize>512||(busw&NAND_BUSWIDTH_16)) ?? ?chip->badblockpos = NAND_LARGE_BADBLOCKS_POS;//大页面flash的坏块信息存储地址为oob信息中的第1个字节开始处 else ?? ?chip->badblockpos = NAND_SMALL_BADBLOCKS_POS;//大页面flash的坏块信息存储地址为oob信息中的第6个字节开始处 对于Samsun和Hynix的MLC型nandflash,坏块标记所在的页是每块的最后一个页,而Samsung,Hynix,和AMD的SLC型nandflash 中,坏块标记分别保存在每块开始的第1,2个页中,其他型号的nandflash大多都保存在第一个也中,为此需要作下标记: 坏块标记保存在块的最后一页中:chip->options |= NAND_BBT_SCANLASTPAGE; 坏块标记保存在块的第1,2页中 :chip->options |= NAND_BBT_SCAN2NDPAGE; nand_scan之后调用nand_scan_tail(mtd)函数, nand_scan_tail(...)函数主要完成MTD实例中各种方法的绑定,例如: 3338 ? ? mtd->read = nand_read; 3339 ? ? mtd->write = nand_write; 3340 ? ? mtd->panic_write = panic_nand_write; 3341 ? ? mtd->read_oob = nand_read_oob; 3342 ? ? mtd->write_oob = nand_write_oob; 3343 ? ? mtd->sync = nand_sync; nand_scan_tail(...)调用chip->scan_bbt()完成坏块表的有关操作。 chip->scan_bbt的绑定过程是在nand_scan_ident()->nand_set_defaults():chip->scan_bbt = nand_default_bbt. 即真正用于坏块操作的是nand_default_bbt函数,该函数在nand_bbt.c中被定义。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |