[PATCH] flashcp copy only different blocks

Harvey Wu (吳崇維) Harvey.Wu at quantatw.com
Mon Oct 26 09:23:53 UTC 2020


The original flashcp process is erase, write and verify all blocks
in one time from file to device.
This patch will add a function that only copy different block data
from file to device. The function will compare block by block between
file and device, then erase write block data from file to device if
found different block.

Signed-off-by: Harvey Wu <Harvey.Wu at quantatw.com>
---
 miscutils/flashcp.c | 89 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/miscutils/flashcp.c b/miscutils/flashcp.c
index 1ca9d158d..7aa4fdb2d 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    -u [-v] FILE MTD_DEVICE      : "
+//usage:       "Copy different blocks from file to dev"
 //usage:#define flashcp_full_usage "\n\n"
 //usage:       "Copy an image 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,75 @@ 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;
+	}
+
+	progress_newline();
+	printf("diff 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;
 	uoff_t erase_count;
 	struct mtd_info_user mtd;
 	struct erase_info_user e;
@@ -69,7 +138,15 @@ 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, "^" "u" "v" "\0" "=2"/*exactly 2 non-option args: file,dev*/);
+	if (strcmp(argv[1], "-u") == 0) {
+		update_check = 1;
+		if (strcmp(argv[2], "-v") == 0)
+			option_mask32 = 1;
+		else
+			option_mask32 = 0;
+	}
+
 	argv += optind;
 //	filename = *argv++;
 //	devicename = *argv;
@@ -106,6 +183,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


_______________________________________________
busybox mailing list
busybox at busybox.net
http://lists.busybox.net/mailman/listinfo/busybox



More information about the busybox mailing list