diff options
Diffstat (limited to 'misc-utils')
-rw-r--r-- | misc-utils/flashcp.c | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/misc-utils/flashcp.c b/misc-utils/flashcp.c index e1be292..9c48637 100644 --- a/misc-utils/flashcp.c +++ b/misc-utils/flashcp.c @@ -64,6 +64,7 @@ #define FLAG_DEVICE 0x08 #define FLAG_ERASE_ALL 0x10 #define FLAG_PARTITION 0x20 +#define FLAG_WR_LAST 0x40 /* error levels */ #define LOG_NORMAL 1 @@ -104,13 +105,14 @@ static NORETURN void showusage(bool error) " %1$s -h | --help\n" " %1$s -V | --version\n" "\n" - " -h | --help Show this help message\n" - " -v | --verbose Show progress reports\n" - " -p | --partition Only copy different block from file to device\n" - " -A | --erase-all Erases the whole device regardless of the image size\n" - " -V | --version Show version information and exit\n" - " <filename> File which you want to copy to flash\n" - " <device> Flash device node or 'mtd:<name>' to write to (e.g. /dev/mtd0, /dev/mtd1, mtd:data, etc.)\n" + " -h | --help Show this help message\n" + " -v | --verbose Show progress reports\n" + " -p | --partition Only copy different block from file to device\n" + " -A | --erase-all Erases the whole device regardless of the image size\n" + " -l | --wr-last=bytes Write the first [bytes] last\n" + " -V | --version Show version information and exit\n" + " <filename> File which you want to copy to flash\n" + " <device> Flash device node or 'mtd:<name>' to write to (e.g. /dev/mtd0, /dev/mtd1, mtd:data, etc.)\n" "\n", PROGRAM_NAME); @@ -219,7 +221,9 @@ int main (int argc,char *argv[]) struct mtd_info_user mtd; struct erase_info_user erase; struct stat filestat; - unsigned char *src,*dest; + unsigned char *src,*dest,*wrlast_buf; + unsigned long long wrlast_len = 0; + int error = 0; /********************* * parse cmd-line @@ -227,12 +231,13 @@ int main (int argc,char *argv[]) for (;;) { int option_index = 0; - static const char *short_options = "hvpAV"; + static const char *short_options = "hvpAl:V"; static const struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"verbose", no_argument, 0, 'v'}, {"partition", no_argument, 0, 'p'}, {"erase-all", no_argument, 0, 'A'}, + {"wr-last", required_argument, 0, 'l'}, {"version", no_argument, 0, 'V'}, {0, 0, 0, 0}, }; @@ -260,6 +265,10 @@ int main (int argc,char *argv[]) flags |= FLAG_ERASE_ALL; DEBUG("Got FLAG_ERASE_ALL\n"); break; + case 'l': + flags |= FLAG_WR_LAST; + wrlast_len = simple_strtoll(optarg, &error); + break; case 'V': common_print_version(); exit(EXIT_SUCCESS); @@ -288,6 +297,10 @@ int main (int argc,char *argv[]) if (flags & FLAG_PARTITION && flags & FLAG_ERASE_ALL) log_failure("Option --partition does not support --erase-all\n"); + if (flags & FLAG_PARTITION && flags & FLAG_WR_LAST) { + log_failure("Option --partition does not support --wr-last\n"); + } + atexit (cleanup); /* get some info about the flash device */ @@ -364,10 +377,40 @@ int main (int argc,char *argv[]) * write the entire file to flash * **********************************/ - log_verbose ("Writing data: 0k/%lluk (0%%)",KB ((unsigned long long)filestat.st_size)); size = filestat.st_size; i = mtd.erasesize; written = 0; + + if ((flags & FLAG_WR_LAST) && (filestat.st_size > wrlast_len)) { + if (wrlast_len > mtd.erasesize) + log_failure("The wrlast (%lluk) is larger than erasesize (%lluk)\n", KB (wrlast_len), KB ((unsigned long long)mtd.erasesize)); + + if (size < mtd.erasesize) i = size; + + log_verbose ("Reading %lluk of data to write last.\n", KB ((unsigned long long)wrlast_len)); + wrlast_buf = malloc(wrlast_len); + if (!wrlast_buf) + log_failure("Malloc failed"); + safe_read (fil_fd, filename, wrlast_buf, wrlast_len); + safe_lseek(dev_fd, wrlast_len, SEEK_SET, device); + written += wrlast_len; + size -= wrlast_len; + i -= wrlast_len; + + log_verbose ("Writing remaining erase block data: %dk/%lluk (%llu%%)\n", + KB (written + i), + KB ((unsigned long long)filestat.st_size), + PERCENTAGE ((unsigned long long)written + i, (unsigned long long)filestat.st_size)); + safe_read (fil_fd, filename, src, i); + safe_write(dev_fd, src, i, written, (unsigned long long)filestat.st_size, device); + + written += i; + size -= i; + i = mtd.erasesize; + } else { + log_verbose ("Writing data: 0k/%lluk (0%%)",KB ((unsigned long long)filestat.st_size)); + } + while (size) { if (size < mtd.erasesize) i = size; @@ -390,6 +433,12 @@ int main (int argc,char *argv[]) KB ((unsigned long long)filestat.st_size)); DEBUG("Wrote %d / %lluk bytes\n",written,(unsigned long long)filestat.st_size); + if ((flags & FLAG_WR_LAST) && (filestat.st_size > wrlast_len)) { + log_verbose ("Writing %lluk of the write last data.\n", KB ((unsigned long long)wrlast_len)); + safe_rewind (dev_fd, device); + safe_write(dev_fd, wrlast_buf, wrlast_len, 0, wrlast_len, device); + } + /********************************** * verify that flash == file data * **********************************/ |