?? mtdcore.c
字號(hào):
//printk("len = %ld\n", len); if (to % mtd->erasesize) { printk("bad alignment\n"); return -1; } part = find_mtd_partition(to); end = part->offset + part->size; to += mtd->erasesize; for(offs = 0; offs < len; offs += mtd->oobblock+mtd->oobsize,to += mtd->oobblock) {
dataptr = &src[offs];
mtd->read_oob(mtd,to,16,&retlen,oobbuff); while (oobbuff[0]!=0xff) { if (to>=end) return -1; to += mtd->erasesize; mtd->read_oob(mtd,to,16,&retlen,oobbuff); } ret = mtd->write_ecc(mtd, to, mtd->oobblock, &retlen, dataptr, dataptr+mtd->oobblock);
if ((ret < 0) || (retlen != mtd->oobblock)) { return ret;
}
} return 0;}static int write_to_nand(struct mtd_info *mtd, loff_t ofs, size_t len, const u_char *buf, int flag){ struct erase_info instr; int ret = 0; __u32 retlen = 0; mtd_partition_t *part; size_t blk_size = find_erase_size(mtd, ofs, len); printk("Found block size = 0x%08lx\n", blk_size); instr.addr = ofs; instr.len = blk_size; if (!(flag & MF_BONFS)) { if (flag & MF_YAFFS) { part = find_mtd_partition(ofs); if (part) { instr.addr = part->offset; instr.len = part->size; } } printk("Erasing... "/*, instr.addr, instr.addr + instr.len*/); ret = mtd->erase(mtd, &instr); if (ret) { printk(" ... failed\n"); return ret; } printk(" ... done\n"); } printk("Writing... "); retlen = 0; if (flag & MF_BONFS) {#ifdef CONFIG_MTD_SMC read_bon_partition(mtd); ret = write_bon_image(mtd, (ulong)ofs, (char *)buf, (long)len); retlen = len;#endif } else if (flag & MF_YAFFS) { ret = write_yaffs_image(mtd, (ulong)ofs, (char *)buf, (long)len); retlen = len; } else { ret = mtd->write(mtd, ofs, len, &retlen, buf); } if ((ret < 0) || (retlen != len)) { printk(" ... failed\n\tretlen = %d, ret = %d\n", retlen, ret); return ret; } else { printk(" ... done\n"); } /* OK. well done. */ printk("NAND Written %d bytes\n", retlen); return 0;}/* * write_to_flash(): write buffer to MTD device * * There are five stages. * Stage 1: Unlock a region if you want. * Stage 2: Erase a region. * Stage 3: Write the buffer to a region. * Stage 4: Verify result of previous stage. * Stage 5: Lock a region if you want. * * Arguments: * ofs: offset to write. * len: length of data to write. * buf: location of buffers. * flag: a flag of a mtd partiton. * */int write_to_flash(loff_t ofs, size_t len, const u_char *buf, int flag){ struct mtd_info *mtd = mtd_get(ofs, len); if (mtd == NULL) { printk("Error. invalid MTD informations\n"); return -1; } switch (mtd->type) { case MTD_NORFLASH: write_to_nor(mtd, ofs, len, buf, flag); break; case MTD_NANDFLASH: write_to_nand(mtd, ofs, len, buf, flag); break; default: printk("Not support this MTD\n"); return -1; } return 0;}/* * User commands */static user_subcommand_t flash_cmds[];static void command_erase(int argc, const char **argv){ struct mtd_info *mtd;// = mymtd; struct erase_info instr; int ret; if ((argc != 2) && (argc != 3)) { printk("invalid 'flash erase' command: too few(many) arguments\n"); return; } if (argc == 2) { mtd_partition_t *part = get_mtd_partition(argv[1]); if (part == NULL) { printk("Could not found partition \"%s\"\n", argv[1]); return; } printk("Erasing \"%s\" parittion\n", argv[1]); instr.addr = part->offset; instr.len = part->size; goto do_erase; } else { instr.addr = strtoul(argv[1], NULL, 0, &ret); instr.len = strtoul(argv[2], NULL, 0, &ret); printk("Erasing block from 0x%08lx to 0x%08lx\n", instr.addr, instr.addr + instr.len); goto do_erase; }do_erase: printk("Erasing block from 0x%08lx to 0x%08lx... ", instr.addr, instr.addr + instr.len); mtd = mtd_get(instr.addr, instr.len); instr.addr -= mtd->baseaddr; ret = mtd->erase(mtd, &instr); if (ret < 0) printk(" ... failed\n"); else printk(" ... done\n");}/*static void command_nandload(int argc, const char **argv){ struct mtd_info *mtd;// = mymtd; loff_t ofs; size_t blk_size, len; size_t retlen; int ret; uchar * to; if (argc != 3) { putstr("invalid 'flash nandload' command: too few(many) arguments\r\n"); return; } ofs = (loff_t)strtoul(argv[1], NULL, 0, NULL); to = (uchar *)strtoul(argv[2], NULL, 0, NULL); //to = (loff_t)0x30008000; printk("Read from NAND 0x%08lx to 0x%08lx ... ", (u32)ofs, (u32)to); //mtd = mtd_typeget(MTD_NANDFLASH); mtd = mtd_get(ofs, 0x20000); if (!mtd) { putstr("failed\r\nmtd=null\r\n"); return; } printk("name:%s mtd_type:%x mtd_size:0x%08lx mtd_baseaddr:0x%08lx ... ", mtd->name, mtd->type, mtd->size, mtd->baseaddr); if (!mtd->read) { putstr("failed\r\nmtd->read=null\r\n"); return; } if (!mtd->read_oob) { putstr("failed\r\nmtd->read_oob=null\r\n"); return; } ret = mtd->read(mtd, ofs-mtd->baseaddr, mtd->oobblock, &retlen, (uchar *)0x30008000); if (ret<0) { putstr("failed\r\n"); return; } ret = mtd->read_oob(mtd, ofs-mtd->baseaddr, mtd->oobsize, &retlen, (uchar *)0x30008000+mtd->oobblock); if (ret<0) { putstr("failed\r\n"); return; } putstr("done\r\n");}*/static void command_lock(int argc, const char **argv){ struct mtd_info *mtd;// = mymtd; loff_t ofs; size_t blk_size, len; if (argc != 3) { putstr("invalid 'flash lock' command: too few(many) arguments\r\n"); return; } ofs = (loff_t)strtoul(argv[1], NULL, 0, NULL); len = (size_t)strtoul(argv[2], NULL, 0, NULL); mtd = mtd_get(ofs, len); blk_size = find_erase_size(mtd, ofs, len); printk("Locking blocks 0x%08lx-0x%08lx... ", (u32)ofs, (u32)(ofs+blk_size)); if (mtd->lock(mtd, ofs, blk_size) < 0) putstr("failed\r\n"); else putstr("done\r\n");}static void command_unlock(int argc, const char **argv){ struct mtd_info *mtd;// = mymtd; loff_t ofs; size_t blk_size, len; if (argc != 3) { putstr("invalid 'flash unlock' command: too few(many) arguments\r\n"); return; } ofs = (loff_t)strtoul(argv[1], NULL, 0, NULL); len = (size_t)strtoul(argv[2], NULL, 0, NULL); mtd = mtd_get(ofs, len); blk_size = find_erase_size(mtd, ofs, len); printk("Unlocking blocks 0x%08lx-0x%08lx... ", (u32)ofs, (u32)(ofs+blk_size)); if (mtd->unlock(mtd, ofs, blk_size) < 0) putstr("failed\r\n"); else putstr("done\r\n");}static void command_info(int argc, const char **argv){ struct mtd_info *mtd; struct map_info *map; struct cfi_private *cfi; struct mtd_erase_region_info *eri; int i; for (i=0;(mtd=mtd_nget(i)) && (mtd->type==MTD_NORFLASH);i++) { map = (struct map_info *)(mtd->priv); cfi = (struct cfi_private *)(map->fldrv_priv); eri = mtd->eraseregions; printk("Flash Memory Information\n" "------------------------\n" "%s: Found %d x%d devices in %d-bit mode\n" " total size: 0x%08lx (%4ldM) bytes\n" " erase block: 0x%08lx (%4ldk) x %d blocks\n\n", map->name, cfi->interleave, cfi->device_type*8, map->buswidth*8, mtd->size, (mtd->size)/(SZ_1M), eri->erasesize, (eri->erasesize)/(SZ_1K), eri->numblocks); }}static void command_help(int argc, const char **argv){ print_usage("flash", flash_cmds);}static user_subcommand_t flash_cmds[] = {{ "help", command_help, "help"}, { "erase", command_erase, "erase [<partition>] or [<start_addr> <length>]" }, { "lock", command_lock, "lock <start_addr> <length>" }, { "unlock", command_unlock, "unlock <start_addr> <length>" }, /*{ "nandload", command_nandload, "nandload <page_addr> <load_addr>" }, */{ "info", command_info, "info" }, { NULL, NULL, NULL }};void command_flash(int argc, const char **argv){ if (mtd_nget(0) == NULL) { printk("Error: Can not find MTD information\n"); return; } if (argc == 1) { printk("invalid 'flash' command: too few arguments\n"); command_help(0, NULL); return; } execsubcmd(flash_cmds, argc-1, argv+1);}static user_command_t flash_cmd = { "flash", command_flash, NULL, "flash [{cmds}] \t\t\t-- Manage Flash memory"};/* * Initialise */extern int mtd_init(void);int mtd_dev_init(void){ int ret = 0; int i;#ifdef CONFIG_DEBUG printk("Initialize MTD device\n");#endif mtdnum = 0; mtd_baseaddr = 0; for (i=0;i<MAXFLASH;i++) { mtd_tbl[i] = NULL; } ret = mtd_init();#ifdef CONFIG_MTD_CFI add_command(&flash_cmd);#endif return ret;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -