[PATCH] misc-utils: flashcp: Add new function that copy only different blocks (original) (raw)

Harvey Wu harveywu95 at gmail.com
Tue Jun 15 02:58:29 UTC 2021


Signed-off-by: Harvey Wu <Harvey.Wu at quantatw.com>

miscutils/flashcp.c | 93 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-)

diff --git a/miscutils/flashcp.c b/miscutils/flashcp.c index 93c80cc6c..f0d231b1e 100644 --- a/miscutils/flashcp.c +++ b/miscutils/flashcp.c @@ -19,7 +19,10 @@ //kbuild:lib-$(CONFIG_FLASHCP) += flashcp.o //usage:#define flashcp_trivial_usage -//usage: "[-v] FILE MTD_DEVICE" +//usage: "\n [-v] FILE MTD_DEVICE : " +//usage: "Copy full image file to dev" +//usage: "\n -p [-v] FILE MTD_DEVICE : " +//usage: "Copy different blocks from file to dev" //usage:#define flashcp_full_usage "\n\n" //usage: "Copy FILE to MTD device\n" //usage: "\n -v Verbose" @@ -44,7 +47,9 @@ static void progress(int mode, uoff_t count, uoff_t total) if (total) percent = (unsigned) (percent / total); printf("\r%s: %"OFF_FMT"u/%"OFF_FMT"u (%u%%) ", - (mode < 0) ? "Erasing block" : ((mode == 0) ? "Writing kb" : "Verifying kb"), + (mode < 0) ? "Erasing block" : + ((mode == 0) ? "Writing kb" : + ((mode == 1) ? "Verifying kb" : "Processing block")), count, total, (unsigned)percent); fflush_all(); } @@ -56,11 +61,77 @@ static void progress_newline(void) bb_putchar('\n'); } +static void copy_diff_blocks(int fd_f,
+ int fd_d,
+ uoff_t erase_count,
+ struct mtd_info_user mtd,
+ struct erase_info_user e,
+ struct stat statb,
+ unsigned char *buf,
+ unsigned char *buf2,
+ char devicename) +{ + int diffblks = 0; + int totalblks = 0; + uoff_t curoffset; + e.start = 0; + uoff_t done; + unsigned count; + + xlseek(fd_f, 0, SEEK_SET); + xlseek(fd_d, 0, SEEK_SET); + done = 0; + count = BUFSIZE; + + while(1) { + uoff_t rem; + + progress(2, done / mtd.erasesize, (uoff_t)statb.st_size / mtd.erasesize); + rem = statb.st_size - done; + if (rem == 0) + break; + if (rem < BUFSIZE) + count = rem; + xread(fd_f, buf, count); + + curoffset = xlseek(fd_d, 0, SEEK_CUR); + totalblks++; + xread(fd_d, buf2, count); + if (memcmp(buf, buf2, count) != 0) { + diffblks++; + if (ioctl(fd_d, MEMERASE, &e) < 0) { + bb_perror_msg_and_die("erase error at 0x%llx on %s", + (long long)e.start, devicename); + } + int ret; + if (count < BUFSIZE) + memset((char)buf + count, 0, BUFSIZE - count); + errno = 0; + xlseek(fd_d, curoffset, SEEK_SET); + ret = full_write(fd_d, buf, BUFSIZE); + if (ret != BUFSIZE) { + bb_perror_msg_and_die("write error at 0x%"OFF_FMT"x on %s, " + "write returned %d", + done, devicename, ret); + } + } + + done += count; + e.start += mtd.erasesize; + } + + if (option_mask32) { + printf("\ndiff blocks : %d/%d\n", diffblks, totalblks); + } +} + int flashcp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int flashcp_main(int argc UNUSED_PARAM, char *argv) { int fd_f, fd_d; / input file and mtd device file descriptors */ int i; + int update_check = 0; + unsigned int opts; uoff_t erase_count; struct mtd_info_user mtd; struct erase_info_user e; @@ -69,7 +140,17 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv) RESERVE_CONFIG_UBUFFER(buf, BUFSIZE); RESERVE_CONFIG_UBUFFER(buf2, BUFSIZE); - /opts =/ getopt32(argv, "^" "v" "\0" "=2"/exactly 2 non-option args: file,dev/); + opts = getopt32(argv, "^" "vp" "\0" "=2"/exactly 2 non-option args: file,dev/); + if (opts & 1) { + option_mask32 = 1; + } + else { + option_mask32 = 0; + } + if (opts & 2) { + update_check = 1; + } + argv += optind; // filename = *argv++; // devicename = *argv; @@ -106,6 +187,12 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv) erase_count = 1; } #endif + + if (update_check) { + copy_diff_blocks(fd_f, fd_d, erase_count, mtd, e, statb, buf, buf2, devicename); + return EXIT_SUCCESS; + } + e.start = 0; for (i = 1; i <= erase_count; i++) { progress(-1, i, erase_count);

2.17.1



More information about the busybox mailing list