AM3352 uboot中对NandFlash坏块的处理
来源:互联网 发布:jo抢购软件下载 编辑:程序博客网 时间:2024/05/22 13:01
本文用于学习uboot中对NandFlash坏块的处理,适用于AM3352,u-boot-2011.09,H27_2G8 NandFlash。
1.1.1 出厂时的坏块标记
依据datasheet中的说明,每2Gb中最多有40个坏块(5MB),且出厂时的第一个块保证不是坏块。
(*) Each 2Gb hasmaximum 40 bad blocks
NOTE: The 1stblock is quranteed to be a valid blick at the time of shipment.
在硬件上,只要每一块的第一页或者第二页的spare area的第一个字节不是FF,即认为这是一个块坏。
Any block wherethe 1st Byte in the spare area of the 1st or 2nd th page (if the 1st page isBad) does not contain FFh is a Bad Block. The Bad Block Information must be readbefore any erase is attempted as the Bad Block Information may be erased.
1.1.2 Uboot的坏块标记
与硬件datasheet说明略有不同的是,uboot将这个坏块标记做了更进一步的区分,使用下面的几种模式进行标记:
static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
在默认情况下,将使用scan_ff_pattern,即与硬件保持一致。
1.1.3 坏块表的建立
在uboot启动时,会快速扫描NandFlash上的坏块并在内存中建立坏块表。
这个过程由下面的函数完成:
/** * create_bbt - [GENERIC] Create a bad block table by scanning the device * @mtd:MTD device structure * @buf:temporary buffer * @bd:descriptor for the good/bad block search pattern * @chip:create the table for a specific chip, -1 read all chips. *Applies only if NAND_BBT_PERCHIP option is set * * Create a bad block table by scanning the device * for the given good/bad block identify pattern */static int create_bbt(struct mtd_info *mtd, uint8_t *buf,struct nand_bbt_descr *bd, int chip)
1.1.4 手工标识坏块
uboot提供了一个叫nand markbad的命令,可以将指定的坏标识为坏块。
使用nand dump.oob命令可以发现,markbad将坏块页的oob前两个字节写为00 00。
1.1.5 擦除所有坏块标记
nand erase支持一个叫scrub的参数,当加上此参数后,nand erase将擦除所有出厂时标定的坏块标记。
1.2 块擦除
当在uboot下执行nand erase时,最终将调用下面的函数:
/** * nand_erase_opts: - erase NAND flash with support for various options * (jffs2 formating) * * @param meminfoNAND device to erase * @param optsoptions, @see struct nand_erase_options * @return0 in case of success * * This code is ported from flash_eraseall.c from Linux mtd utils by * Arcom Control System Ltd. */int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts)
1.2.1 对已有坏块的处理
当执行擦除操作时,除非指定scrub参数,否则将直接跳过坏块的处理:
if (!opts->scrub && bbtest) {int ret = meminfo->block_isbad(meminfo, erase.addr);if (ret > 0) {if (!opts->quiet)printf("\rSkipping bad block at " "0x%08llx " " \n", erase.addr);if (!opts->spread)erased_length++;continue;} else if (ret < 0) {printf("\n%s: MTD get bad block failed: %d\n", mtd_device, ret);return -1;}}
1.2.2 擦除时坏块的处理
当擦除发现坏块而导致擦除失败时,uboot没有做任何处理,直接返回。
/** * nand_erase_nand - [Internal] erase block(s) * @mtd:MTD device structure * @instr:erase instruction * @allowbbt:allow erasing the bbt area * * Erase one ore more blocks */int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, int allowbbt){.....chip->erase_cmd(mtd, page & chip->pagemask);status = chip->waitfunc(mtd, chip);/* * See if operation failed and additional status checks are * available */if ((status & NAND_STATUS_FAIL) && (chip->errstat))status = chip->errstat(mtd, chip, FL_ERASING, status, page);/* See if block erase succeeded */if (status & NAND_STATUS_FAIL) {MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);instr->state = MTD_ERASE_FAILED;instr->fail_addr = ((loff_t)page << chip->page_shift);goto erase_exit;}......}
1.3 写入操作
当在uboot下使用nand write写入时,实际执行下面的函数:
/** * nand_write_skip_bad: * * Write image to NAND flash. * Blocks that are marked bad are skipped and the is written to the next * block instead as long as the image is short enough to fit even after * skipping the bad blocks. * * @param nand NAND device * @param offsetoffset in flash * @param lengthbuffer length * @param buffer buffer to read from * @param flagsflags modifying the behaviour of the write to NAND * @return0 in case of success */int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,u_char *buffer, int flags)
从下面的代码可以看出nand write对坏块的处理:
while (left_to_write > 0) {size_t block_offset = offset & (nand->erasesize - 1);size_t write_size, truncated_write_size;WATCHDOG_RESET ();if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {printf ("Skip bad block 0x%08llx\n",offset & ~(nand->erasesize - 1));offset += nand->erasesize - block_offset;continue;}......left_to_write -= write_size;}
也就是说,nandwrite将跳过坏块并持续到数据完全写入。
此操作保证数据的完全写入,除非NandFlash已经没有空间。
1.4 读取操作
nand读取操作由下面的函数实现:
/** * nand_read_skip_bad: * * Read image from NAND flash. * Blocks that are marked bad are skipped and the next block is readen * instead as long as the image is short enough to fit even after skipping the * bad blocks. * * @param nand NAND device * @param offset offset in flash * @param length buffer length, on return holds remaining bytes to read * @param buffer buffer to write to * @return 0 in case of success */int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer)
下面是它的读取流程。
while (left_to_read > 0) {size_t block_offset = offset & (nand->erasesize - 1);size_t read_length;WATCHDOG_RESET ();if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {printf ("Skipping bad block 0x%08llx\n",offset & ~(nand->erasesize - 1));offset += nand->erasesize - block_offset;continue;}.....left_to_read -= read_length;offset += read_length;p_buffer += read_length;}
可以明确,读取操作保证读取足够数量的数据,当有坏块时直接跳过坏块。
- AM3352 uboot中对NandFlash坏块的处理
- 对于nandflash坏块的一些处理办法
- mini2440 tq2440 vivi uboot 去除nandflash坏块
- nandflash坏块管理机制
- nandflash坏块管理机制
- NandFlash 坏块
- NANDFlash坏块管理研究
- 关于NandFlash坏块的一些理解(基于K9F2G08)
- 深层解决cramfs文件系统不支持nandflash坏块的解决办法
- 数据库坏块的处理
- linux内核中对nand的坏块管理
- wince系统中对nand坏块的修正
- Nand Flash设计中针对坏块处理的理解
- lob表中出现坏块的处理方法
- nanddump读出nandflash包括坏块
- 对Oracle数据库坏块的理解
- ReiserFS文件系统坏块的处理
- 坏块的处理与恢复!
- oracle11g 云上dataguard 在线降低cpu内存 50% 后报错误ORA-27101的处理过程
- 欢迎使用CSDN-markdown编辑器
- C#做的接口
- 控件,代理为什么使用Weak?
- Exynos4412搭建最小文件系统
- AM3352 uboot中对NandFlash坏块的处理
- 自主分析input与button标签之间的区别
- Neural Networks
- 【步兵 lua】模拟继承
- Mysql实用SQL语句总结(持续更新)
- Oracle 11G Client 客户端安装
- 电商评价质量评分模型(一)
- python的print函数的一些功能
- 第二章 java基础(单行和多行注释)