int FRead(char *dst, int src, int count) { int i, o, off, cnt, addr, fd, len; unsigned char *buf, *p; if (flash_mtd_init_info()) return -1; #ifdef DEBUG printf("%s: src %x, count %d\n", __func__, src, count); #endif buf = (unsigned char *)malloc(count); if (buf == NULL) { fprintf(stderr, "fail to alloc memory for %d bytes\n", count); return -1; } p = buf; cnt = count; off = src; for (i = 0, addr = 0; i < NUM_INFO; i++) { if (addr <= off && off < addr + info[i].size) { o = off - addr; fd = flash_mtd_open(i, O_RDONLY | O_SYNC); if (fd < 0) { fprintf(stderr, "failed to open mtd%d\n", i); free(buf); return -1; } lseek(fd, o, SEEK_SET); len = ((o + cnt) < info[i].size)? cnt : (info[i].size - o); #ifdef DEBUG printf(" read from mtd%d: o %x, len %d\n", i, o, len); #endif read(fd, p, len); close(fd); cnt -= len; if (cnt == 0) break; off += len; p += len; } addr += info[i].size; } memcpy(dst, buf, count); #ifdef DEBUG for (i = 0, p = buf; i < count; i++, p++) { #if 1 //backward compatibility printf("%X: %X\n", src + i, *p); #else printf("%02x", *p); if (i % 2 == 1) printf(" "); #endif } #endif free(buf); return 0; }
int flash_mtd_erase(int start, int end) { int i, addr, fd; struct erase_info_user ei; debug("%s: start %x, end %x\n", __func__, start, end); for (i = 0, addr = 0; i < NUM_INFO; i++) { if (addr <= start && start < addr + info[i].size) { if (end < start || end >= addr + info[i].size) { fprintf(stderr, "not support\n"); return -1; } fd = flash_mtd_open(i, O_RDWR | O_SYNC); if (fd < 0) { fprintf(stderr, "failed to open mtd%d\n", i); return -1; } ei.start = start - addr; ei.length = end - start + 1; debug(" erase mtd%d, start %x, len %x\n", i, ei.start, ei.length); if (ioctl(fd, MEMERASE, &ei) < 0) { fprintf(stderr, "failed to erase mtd%d\n", i); close(fd); return -1; } close(fd); break; } addr += info[i].size; } printf("Erase Addr From %0X To %0X\n", start, end); return 0; }
/** * Equal to original FRead(). * Don't use this function to read data from Factory partition directly. * Call FRead() with old absolute address of flash or call FactoryRead() * with relative address regards to Factory partition instead. */ int FlashRead(const unsigned char *dst, int src, int count) { int i, o, off, cnt, addr, fd, len; unsigned char *buf, *p; if (flash_mtd_init_info()) return -1; debug("%s: src %x, count %d\n", __func__, src, count); buf = malloc(count); if (buf == NULL) { fprintf(stderr, "fail to alloc memory for %d bytes\n", count); return -1; } p = buf; cnt = count; off = src; for (i = 0, addr = 0; i < NUM_INFO; i++) { if (addr <= off && off < addr + info[i].size) { o = off - addr; fd = flash_mtd_open(i, O_RDONLY | O_SYNC); if (fd < 0) { fprintf(stderr, "failed to open mtd%d\n", i); free(buf); return -1; } lseek(fd, o, SEEK_SET); len = ((o + cnt) < info[i].size)? cnt : (info[i].size - o); debug(" read from mtd%d: o %x, len %d\n", i, o, len); read(fd, p, len); close(fd); cnt -= len; if (cnt == 0) break; off += len; p += len; } addr += info[i].size; } memcpy((void*) dst, buf, count); free(buf); return 0; }
int FWrite(char *src, int offset, int count) { int i, o, fd, off, addr, sz; unsigned char *buf; struct erase_info_user ei; if (flash_mtd_init_info()) return -1; #ifdef DEBUG printf("%s: offset %x, src string", __func__, offset); for (i = 0; i < count; i++) printf(" %x", (unsigned char) *(src + i)); printf("\n"); #endif off = offset; for (i = 0, addr = 0; i < NUM_INFO; i++) { if (addr <= off && off < addr + info[i].size) { sz = info[i].erasesize; buf = (unsigned char *)malloc(sz); if (buf == NULL) { fprintf(stderr, "failed to alloc memory for %d bytes\n", sz); return -1; } fd = flash_mtd_open(i, O_RDWR | O_SYNC); if (fd < 0) { fprintf(stderr, "failed to open mtd%d\n", i); free(buf); return -1; } off -= addr; o = (off / sz) * sz; lseek(fd, o, SEEK_SET); #ifdef DEBUG printf(" backup mtd%d, o %x(off %x), len %x\n", i, o, off, sz); #endif //backup if (read(fd, buf, sz) != sz) { fprintf(stderr, "failed to read %d bytes from mtd%d\n", sz, i); free(buf); close(fd); return -1; } //erase ei.start = o; ei.length = sz; if (ioctl(fd, MEMERASE, &ei) < 0) { fprintf(stderr, "failed to erase mtd%d\n", i); free(buf); close(fd); return -1; } //write lseek(fd, o, SEEK_SET); #ifdef DEBUG for (i = 0; i < count; i++) printf(" buf[%x] = %x\n", off - o + i, (unsigned char)*(src + i)); printf("\n"); #endif // *(buf + (off - o)) = (unsigned char)value; memcpy(buf + (off - o), src, count); if (write(fd, buf, sz) == -1) { fprintf(stderr, "failed to write mtd%d\n", i); free(buf); close(fd); return -1; } free(buf); close(fd); break; } addr += info[i].size; } buf = (unsigned char *)malloc(count); FRead(buf, offset, count); free(buf); return 0; }
int flash_mtd_write(int offset, int value) { int i, o, fd, off, addr, sz; unsigned char *buf; struct erase_info_user ei; debug("%s: offset %x, value %x\n", __func__, offset, (unsigned char)value); off = offset; for (i = 0, addr = 0; i < NUM_INFO; i++) { if (addr <= off && off < addr + info[i].size) { sz = info[i].erasesize; buf = (unsigned char *)malloc(sz); if (buf == NULL) { fprintf(stderr, "failed to alloc memory for %d bytes\n", sz); return -1; } fd = flash_mtd_open(i, O_RDWR | O_SYNC); if (fd < 0) { fprintf(stderr, "failed to open mtd%d\n", i); free(buf); return -1; } off -= addr; o = (off / sz) * sz; lseek(fd, o, SEEK_SET); debug(" backup mtd%d, o %x(off %x), len %x\n", i, o, off, sz); //backup if (read(fd, buf, sz) != sz) { fprintf(stderr, "failed to read %d bytes from mtd%d\n", sz, i); free(buf); close(fd); return -1; } //erase ei.start = o; ei.length = sz; if (ioctl(fd, MEMERASE, &ei) < 0) { fprintf(stderr, "failed to erase mtd%d\n", i); free(buf); close(fd); return -1; } //write lseek(fd, o, SEEK_SET); debug(" buf[%x] = %x\n", off - o, (unsigned char)value); *(buf + (off - o)) = (unsigned char)value; if (write(fd, buf, sz) == -1) { fprintf(stderr, "failed to write mtd%d\n", i); free(buf); close(fd); return -1; } free(buf); close(fd); break; } addr += info[i].size; } printf("Write %0X to %0X\n", (unsigned char)value, offset); return 0; }