int do_insAndroidUserImage(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int ret = 0; nand_write_options_t opts; memset(&opts, 0, sizeof(opts)); //------------------------------------------------------------------ opts.pad = 0; opts.blockalign = 1; opts.writeoob = 1; opts.autoplace = 1; opts.offset = 0x9000000; opts.length = readl(0x27FFFFE8); opts.buffer = readl(0x27FFFFE0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; printf("Start Addr : %X, Size : %X \n",opts.buffer,opts.length); nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed User Data \n"); printf("Installed Android UserData Image image. \n"); return ret == 0 ? 0 : 1; return 1; }
int do_insAndroidRamdisk(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int ret = 0; nand_write_options_t opts; memset(&opts, 0, sizeof(opts)); opts.pad = 1; opts.blockalign = 1; opts.writeoob = 0; opts.autoplace = 1; //------------------------------------------------------------------ printf("Start android Ramdisk installation. \n"); opts.offset = 0x600000; opts.length = readl(0x27FFFFC8); opts.buffer = readl(0x27FFFFC0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed Ramdisk \n"); printf("Installed Android Ramdisk image. \n"); return ret == 0 ? 0 : 1; return 1; }
/* Write nboot loader image into the nand flash */ int nand_burn_nboot_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int filesize; MV_U32 ret = 0; extern char console_buffer[]; nand_info_t *nand = &nand_info[0]; nand_erase_options_t er_opts; nand_write_options_t wr_opts; load_addr = CFG_LOAD_ADDR; if(argc == 2) { copy_filename (BootFile, argv[1], sizeof(BootFile)); } else { copy_filename (BootFile, "nboot.bin", sizeof(BootFile)); printf("using default file \"nboot.bin\" \n"); } if ((filesize = NetLoop(TFTP)) < 0) return 0; printf("Erase %d - %d ... ",CFG_NBOOT_BASE, CFG_NBOOT_LEN); memset(&er_opts, 0, sizeof(er_opts)); er_opts.offset = CFG_NBOOT_BASE; er_opts.length = CFG_NBOOT_LEN; er_opts.quiet = 1; nand_erase_opts(nand, &er_opts); //nand_erase(nand_dev_desc + 0, CFG_NBOOT_BASE, CFG_NBOOT_LEN , 0); printf("\nCopy to Nand Flash... "); memset(&wr_opts, 0, sizeof(wr_opts)); wr_opts.buffer = (u_char*) load_addr; wr_opts.length = CFG_NBOOT_LEN; wr_opts.offset = CFG_NBOOT_BASE; /* opts.forcejffs2 = 1; */ wr_opts.pad = 1; wr_opts.blockalign = 1; wr_opts.quiet = 1; ret = nand_write_opts(nand, &wr_opts); /* ret = nand_rw(nand_dev_desc + 0, NANDRW_WRITE | NANDRW_JFFS2, CFG_NBOOT_BASE, CFG_NBOOT_LEN, &total, (u_char*)0x100000); */ if (ret) printf("Error - NAND burn faild!\n"); else printf("\ndone\n"); return 1; }
int do_insAndroid(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int ret = 0; nand_write_options_t opts; memset(&opts, 0, sizeof(opts)); opts.pad = 1; opts.blockalign = 1; opts.writeoob = 0; opts.autoplace = 1; //------------------------------------------------------------------ printf("Start android installation. \n"); opts.offset = 0x0; opts.length = readl(0x27FFFFA8); opts.buffer = readl(0x27FFFFA0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed uBoot \n"); opts.offset = 0x200000; opts.length = readl(0x27FFFFB8); opts.buffer = readl(0x27FFFFB0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed zImaget \n"); opts.offset = 0x600000; opts.length = readl(0x27FFFFC8); opts.buffer = readl(0x27FFFFC0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed Ramdisk Image \n"); //------------------------------------------------------------------ udelay (1000); opts.pad = 0; opts.blockalign = 1; opts.writeoob = 1; opts.autoplace = 1; opts.offset = 0xA00000; opts.length = readl(0x27FFFFD8); opts.buffer = readl(0x27FFFFD0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; printf("Start Addr : %X, Size : %X \n",opts.buffer,opts.length); nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed System Image \n"); udelay (1000); opts.offset = 0x9000000; opts.length = readl(0x27FFFFE8); opts.buffer = readl(0x27FFFFE0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; printf("Start Addr : %X, Size : %X \n",opts.buffer,opts.length); nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed User Data \n"); printf("Android Installation OK. \n"); return ret == 0 ? 0 : 1; return 1; }
/******************************************************************************* * mvNandReadWriteTest - Performs read-write test on NAND chip. * * DESCRIPTION: * This routine writes pattern 0x55,0xaa in 16 blocks at offset immediately * after ENV section and reads them back and verifies. * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * Returns 1 on failure, else 0 *******************************************************************************/ int mvNandReadWriteTest(void) { int i,j,ret; int testFlag; unsigned int pageSize; unsigned char rbuf[2048]; nand_write_options_t wr_opts; nand_erase_options_t er_opts; nand_read_options_t rd_opts; testFlag = DIAG_PASS; printf("\tNAND read/write test "); do { pageSize = nand_info[0].oobblock; /***************** ERASE ***********************/ memset(&er_opts, 0, sizeof(er_opts)); er_opts.offset = CFG_ENV_OFFSET + CFG_ENV_SIZE; er_opts.length = pageSize * PAGES_PER_BLOCK * 16; er_opts.quiet = 1; ret = nand_erase_opts(&nand_info[0], &er_opts); if (ret) { printf("\tError: NAND Erase faild!\n"); testFlag = DIAG_FAIL; break; } if(DIAG_PASS != testFlag) { break; } /***************** WRITE ***********************/ memset(&wr_opts, 0, sizeof(wr_opts)); for(i=0; i < pageSize; i=i+2) { wr_opts.buffer[i] = 0x55; wr_opts.buffer[i+1] = 0xaa; } wr_opts.length = pageSize; wr_opts.offset = CFG_ENV_OFFSET + CFG_ENV_SIZE; /* opts.forcejffs2 = 1; */ wr_opts.pad = 1; wr_opts.blockalign = 1; wr_opts.quiet = 1; for(i=0; i < PAGES_PER_BLOCK * 16;i++) { ret = nand_write_opts(&nand_info[0], &wr_opts); if (ret) { printf("\tError: NAND write faild!\n"); testFlag = DIAG_FAIL; break; } wr_opts.offset += pageSize; } if(DIAG_PASS != testFlag) { break; } /**************** READ *************************/ memset(&rd_opts, 0, sizeof(rd_opts)); rd_opts.buffer = rbuf; rd_opts.length = (ulong)pageSize; rd_opts.offset = CFG_ENV_OFFSET + CFG_ENV_SIZE; rd_opts.quiet = 1; for(i=0; i < PAGES_PER_BLOCK * 16;i++) { ret = nand_read_opts(&nand_info[0], &rd_opts); if (ret) { printf("\tError: NAND read faild!\n"); testFlag = DIAG_FAIL; break; } for(j=0; j < pageSize; j=j+4) { if (rbuf[j] != 0x55 && rbuf[j+1] != 0xaa && rbuf[j+2] != 0x55 && rbuf[j+3] != 0xaa) { printf("\tError: Data verify failed\n"); testFlag = DIAG_FAIL; break; } } rd_opts.offset += pageSize; } if(DIAG_PASS != testFlag) { break; } }while(0); printf((testFlag==DIAG_PASS)?"PASSED\n":"FAIL\n"); return testFlag; }
/* Write u-boot image into the nand flash */ int nand_burn_uboot_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int filesize; MV_U32 ret = 0; extern char console_buffer[]; nand_info_t *nand = &nand_info[0]; nand_erase_options_t er_opts; nand_write_options_t wr_opts; load_addr = CFG_LOAD_ADDR; if(argc == 2) { copy_filename (BootFile, argv[1], sizeof(BootFile)); } else { copy_filename (BootFile, "u-boot.bin", sizeof(BootFile)); printf("using default file \"u-boot.bin\" \n"); } if ((filesize = NetLoop(TFTP)) < 0) return 0; printf("\n**Warning**\n"); printf("If U-Boot Endiannes is going to change (LE->BE or BE->LE), Then Env parameters should be overriden..\n"); printf("Override Env parameters? (y/n)"); readline(" "); if( strcmp(console_buffer,"Y") == 0 || strcmp(console_buffer,"yes") == 0 || strcmp(console_buffer,"y") == 0 ) { printf("Erase Env parameters sector %d... ",CFG_ENV_OFFSET); memset(&er_opts, 0, sizeof(er_opts)); er_opts.offset = CFG_ENV_OFFSET; er_opts.length = CFG_ENV_SECT_SIZE; er_opts.quiet = 1; nand_erase_opts(nand, &er_opts); //nand_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SECT_SIZE, 0); printf("\n"); } printf("Erase %d - %d ... ",CFG_MONITOR_BASE, CFG_MONITOR_LEN); memset(&er_opts, 0, sizeof(er_opts)); er_opts.offset = CFG_MONITOR_BASE; er_opts.length = CFG_MONITOR_LEN; er_opts.quiet = 1; nand_erase_opts(nand, &er_opts); //nand_erase(nand_dev_desc + 0, CFG_MONITOR_BASE, CFG_MONITOR_LEN, 0); printf("\nCopy to Nand Flash... "); memset(&wr_opts, 0, sizeof(wr_opts)); wr_opts.buffer = (u_char*) load_addr; wr_opts.length = CFG_MONITOR_LEN; wr_opts.offset = CFG_MONITOR_BASE; /* opts.forcejffs2 = 1; */ wr_opts.pad = 1; wr_opts.blockalign = 1; wr_opts.quiet = 1; ret = nand_write_opts(nand, &wr_opts); /* ret = nand_rw(nand_dev_desc + 0, NANDRW_WRITE | NANDRW_JFFS2, CFG_MONITOR_BASE, CFG_MONITOR_LEN, &total, (u_char*)0x100000 + CFG_MONITOR_IMAGE_OFFSET); */ if (ret) printf("Error - NAND burn faild!\n"); else printf("\ndone\n"); return 1; }
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int i, dev, ret = 0; ulong addr, off; size_t size; char *cmd, *s; nand_info_t *nand; #ifdef CONFIG_SYS_NAND_QUIET int quiet = CONFIG_SYS_NAND_QUIET; #else int quiet = 0; #endif const char *quiet_str = getenv("quiet"); /* at least two arguments please */ if (argc < 2) goto usage; if (quiet_str) quiet = simple_strtoul(quiet_str, NULL, 0) != 0; cmd = argv[1]; if (strcmp(cmd, "info") == 0) { putc('\n'); for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) { if (nand_info[i].name) nand_print_info(i); } return 0; } if (strcmp(cmd, "device") == 0) { if (argc < 3) { putc('\n'); if ((nand_curr_device < 0) || (nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE)) puts("no devices available\n"); else nand_print_info(nand_curr_device); return 0; } dev = (int)simple_strtoul(argv[2], NULL, 10); if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[dev].name) { puts("No such device\n"); return 1; } printf("Device %d: %s", dev, nand_info[dev].name); puts("... is now current device\n"); nand_curr_device = dev; #ifdef CONFIG_SYS_NAND_SELECT_DEVICE /* * Select the chip in the board/cpu specific driver */ board_nand_select_device(nand_info[dev].priv, dev); #endif return 0; } if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && strncmp(cmd, "dump", 4) != 0 && strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && strcmp(cmd, "biterr") != 0 && strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) goto usage; /* the following commands operate on the current device */ if (nand_curr_device < 0 || nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[nand_curr_device].name) { puts("\nno devices available\n"); return 1; } nand = &nand_info[nand_curr_device]; if (strcmp(cmd, "bad") == 0) { printf("\nDevice %d bad blocks:\n", nand_curr_device); for (off = 0; off < nand->size; off += nand->erasesize) if (nand_block_isbad(nand, off)) printf(" %08lx\n", off); return 0; } /* * Syntax is: * 0 1 2 3 4 * nand erase [clean] [off size] */ if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) { nand_erase_options_t opts; /* "clean" at index 2 means request to write cleanmarker */ int clean = argc > 2 && !strcmp("clean", argv[2]); int o = clean ? 3 : 2; int scrub = !strcmp(cmd, "scrub"); printf("\nNAND %s: ", scrub ? "scrub" : "erase"); /* skip first two or three arguments, look for offset and size */ if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0) return 1; memset(&opts, 0, sizeof(opts)); opts.offset = off; opts.length = size; opts.jffs2 = clean; opts.quiet = quiet; if (scrub) { puts("Warning: " "scrub option will erase all factory set " "bad blocks!\n" " " "There is no reliable way to recover them.\n" " " "Use this command only for testing purposes " "if you\n" " " "are sure of what you are doing!\n" "\nReally scrub this NAND flash? <y/N>\n"); if (getc() == 'y' && getc() == '\r') { opts.scrub = 1; } else { puts("scrub aborted\n"); return -1; } } ret = nand_erase_opts(nand, &opts); printf("%s\n", ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; } if (strncmp(cmd, "dump", 4) == 0) { if (argc < 3) goto usage; s = strchr(cmd, '.'); off = (int)simple_strtoul(argv[2], NULL, 16); if (s != NULL && strcmp(s, ".oob") == 0) ret = nand_dump(nand, off, 1); else ret = nand_dump(nand, off, 0); return ret == 0 ? 1 : 0; } if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { int read; if (argc < 4) goto usage; addr = (ulong)simple_strtoul(argv[2], NULL, 16); read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ printf("\nNAND %s: ", read ? "read" : "write"); if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) return 1; s = strchr(cmd, '.'); if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) { if (read) ret = nand_read_skip_bad(nand, off, &size, (u_char *)addr); else ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr); } else if (!read && s != NULL && + (!strcmp(s, ".yaffs") || !strcmp(s, ".yaffs1"))) { nand_write_options_t opts; memset(&opts, 0, sizeof(opts)); opts.buffer = (u_char*) addr; opts.length = size; opts.offset = off; opts.pad = 0; opts.blockalign = 1; opts.quiet = quiet; opts.writeoob = 1; opts.autoplace = 1; ret = nand_write_opts(nand, &opts); } else if (!strcmp(s, ".oob")) { /* out-of-band data */ mtd_oob_ops_t ops = { .oobbuf = (u8 *)addr, .ooblen = size, .mode = MTD_OOB_RAW }; if (read) ret = nand->read_oob(nand, off, &ops); else ret = nand->write_oob(nand, off, &ops); } else {