[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
- Previous message (by thread): [PATCH] vi: initialise tabstop once not for each file
- Next message (by thread): [PATCH] misc-utils: flashcp: Add new function that copy only different blocks
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
- 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 | 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
- Previous message (by thread): [PATCH] vi: initialise tabstop once not for each file
- Next message (by thread): [PATCH] misc-utils: flashcp: Add new function that copy only different blocks
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]