void nvm_dump(void) { int env_valid = 0; int isEnv1Bad = -1; int isEnv2Bad = -1; struct mtd_info_user info; env_t *env_ptr = NULL; if( CMM_SUCCESS != get_mtd_info("/dev/mtd2", &info) ) { printf(" ERROR: can not get mtd info\n"); return; } isEnv1Bad = check_block("/dev/mtd2", 0); isEnv2Bad = check_block("/dev/mtd2", CFG_ENV_SIZE); if( -1 == isEnv1Bad ) { printf(" ERROR: check env block 1 failed\n"); return; } if( -1 == isEnv2Bad ) { printf(" ERROR: check env block 2 failed\n"); return; } if( ( isEnv1Bad != 0 ) || ( isEnv2Bad != 0 ) ) { printf(" ERROR: env is broken\n"); return; } env_ptr = env_init(&env_valid); if( NULL == env_ptr ) { printf(" ERROR: read env failed\n"); return; } printf("nvm device name: mtd2\n"); printf("device type: %d\n", info.type); printf("nvm total size: %d KiB\n", info.size/1024); printf("block size: %d KiB\n", info.erasesize/1024); printf("page size: %d KiB\n", info.writesize/1024); printf("oob size: %d bytes\n", info.oobsize); printf("bad blocks: 0\n"); printf("env config size: %d KiB\n", CFG_ENV_SIZE/1024); printf("env valid: %d\n", env_valid); __debug_printf_env(env_ptr); env_destroy(env_ptr); }
void loadbin(void) { void (*go)(void); struct img_header *head = (struct img_header *)DEFAULT_LOADADDR; struct mtd_info *mtd = get_mtd_info(); #if 1 check_magic(head); mtd->nf_erase(mtd, 0x0, head->img_size); mtd->nf_write(mtd, 0x0, (void *)((u8*)head + head->img_offset), &head->img_size); go = (void *)((u8 *)head + head->img_offset); #else u32 len = 240; mtd->nf_read(mtd, 0, (void *)DEFAULT_LOADADDR, &len); go = (void *)DEFAULT_LOADADDR; #endif // go(); puts("loadbin(): image download complete.\n"); }
/** * Read data from specificed partition. * @mtd_name: MTD partition name. such as "Bootloader", "Factory", etc * @offset: offset in MTD partition. (start from 0) * @buf: * @count: * @return: * 0: Successful * -1: Invalid parameter or error occurs. * -2: Out of Factory partition. * -3: Open MTD partition fail. */ int MTDPartitionRead(const char *mtd_name, const unsigned char *buf, int offset, int count) { int cnt, fd, ret; unsigned char *p; struct mtd_info info, *mi = &info; if (!mtd_name || *mtd_name == '\0' || !buf || offset < 0 || count <= 0 || get_mtd_info(mtd_name, mi) < 0) return -1; if ((offset + count) > mi->size) { fprintf(stderr, "%s: Out of Factory partition. (offset 0x%x count 0x%x)\n", __func__, offset, count); return -2; } if ((fd = flash_mtd_open_name(mi->dev, O_RDONLY | O_SYNC)) < 0) { fprintf(stderr, "failed to open %s. (errno %d (%s))\n", mi->dev, errno, strerror(errno)); return -3; } debug("%s: %s offset %x, count %d\n", __func__, mtd_name, offset, count); lseek(fd, offset, SEEK_SET); p = (unsigned char*) buf; cnt = count; while (cnt > 0) { ret = read(fd, p, cnt); if (ret > 0) { cnt -= ret; continue; } fprintf(stderr, "%s: Read fail! (offset 0x%x, count 0x%x, cnt 0x%x, errno %d (%s))\n", __func__, offset, count, cnt, errno, strerror(errno)); break; } close(fd); return 0; }
/** * Write data to Factory partition. * @mtd_name: MTD partition name. such as "Bootloader", "Factory", etc * @buf: * @offset: offset in Factory partition. (start from 0; NOT 0x40000) * @count: * @return: * 0: Successful * -1: Invalid parameter or error occurs. * -2: Out of Factory partition. * -3: Open MTD partition fail. * -4: Malloc buffer for erase procedure fail. * -5: Aligned offset and length exceeds MTD partition. * -6: Malloc buffer for alignment offset and/or length to write size fail. * -7: Read data for alignment data fail. */ int MTDPartitionWrite(const char *mtd_name, const unsigned char *buf, int offset, int count) { int fd, o, off, cnt, ret = 0, len; unsigned char *tmp; const unsigned char *p = buf; unsigned char *tmp_buf = NULL; struct erase_info_user ei; struct mtd_info info, *mi = &info; int old_offset, old_count; if (!mtd_name || *mtd_name == '\0' || !buf || offset < 0 || count <= 0 || get_mtd_info(mtd_name, mi) < 0) return -1; if ((offset + count) > mi->size) { fprintf(stderr, "%s: Out of %s partition. (offset 0x%x count 0x%x)\n", __func__, mi->name, offset, count); return -2; } /* Align offset and length to write size of UBI volume backed MTD device. */ old_offset = offset; old_count = count; if (mi->type == MTD_UBIVOLUME) { int e = ROUNDUP(offset + count, mi->writesize), o; offset = ROUNDDOWN(offset, mi->writesize); count = e - offset; debug("%s: offset %x -> %x, count %x -> %x, mtd->writesize %x\n", __func__, old_offset, offset, old_count, count, mi->writesize); if ((offset + count) > mi->size) { fprintf(stderr, "%s: Out of %s partition. (aligned offset 0x%x count 0x%x)\n", __func__, mi->name, offset, count); return -5; } if (old_offset != offset || old_count != count) { tmp_buf = malloc(count); if (!tmp_buf) { fprintf(stderr, "%s: allocate buffer fail!\n", __func__); return -6; } if (MTDPartitionRead(mtd_name, tmp_buf, offset, count)) { fprintf(stderr, "%s: read data fail!\n", __func__); return -7; } o = old_offset - offset; memcpy(tmp_buf + o, buf, old_count); p = tmp_buf; } } #ifdef DEBUG debug("%s: %s offset %x, buf string", __func__, mtd_name, offset); { int i, len = (count > MAX_DUMP_LEN)? MAX_DUMP_LEN:count; for (i = 0; i < len; i++) debug(" %x", (unsigned char) *(buf + i)); debug("%s\n", (len == count)? "":"..."); } #endif fd = flash_mtd_open_name(mi->dev, O_RDWR | O_SYNC); if (fd < 0) { fprintf(stderr, "%s: failed to open %s. (errno %d (%s))\n", __func__, mi->dev, errno, strerror(errno)); if (tmp_buf) free(tmp_buf); return -3; } tmp = malloc(mi->erasesize); if (!tmp) { fprintf(stderr, "%s: failed to alloc memory for %d bytes\n", __func__, mi->erasesize); if (tmp_buf) free(tmp_buf); return -4; } off = offset; cnt = count; while (cnt > 0) { o = off & ~(mi->erasesize - 1); /* aligned to erase boundary */ len = mi->erasesize - (off - o); if (cnt < len) len = cnt; lseek(fd, o, SEEK_SET); debug(" backup %s, o %x(off %x), len %x\n", mi->dev, o, off, mi->erasesize); //backup if (read(fd, tmp, mi->erasesize) != mi->erasesize) { fprintf(stderr, "%s: failed to read %d bytes from %s\n", __func__, mi->erasesize, mi->dev); ret = -5; break; } //erase ei.start = o; ei.length = mi->erasesize; if (ioctl(fd, MEMERASE, &ei) < 0) { fprintf(stderr, "%s: failed to erase %s start 0x%x length 0x%x. errno %d (%s)\n", __func__, mi->dev, ei.start, ei.length, errno, strerror(errno)); ret = -6; break; } //write lseek(fd, o, SEEK_SET); #ifdef DEBUG { int i, len = (count > MAX_DUMP_LEN)? MAX_DUMP_LEN:count; for (i = 0; i < len; i++) debug(" tmp[%x] = %x\n", off - o + i, (unsigned char)*(buf + i)); debug("%s\n", (len == count)? "":"..."); } #endif memcpy(tmp + (off - o), p, len); if (write(fd, tmp, mi->erasesize) != mi->erasesize) { fprintf(stderr, "%s: failed to write %s\n", __func__, mi->dev); ret = -7; break; } p += len; off += len; cnt -= len; } free(tmp); free(tmp_buf); if (!cnt) { tmp = (unsigned char *)malloc(count); MTDPartitionRead(mtd_name, tmp, offset, count); free(tmp); } return ret; }