| diff --git a/nanddump.c b/nanddump.c |
| index be458c6..700bdcf 100644 |
| --- a/nanddump.c |
| +++ b/nanddump.c |
| @@ -53,6 +53,7 @@ static void display_help(void) |
| "-p --prettyprint Print nice (hexdump)\n" |
| "-q --quiet Don't display progress and status messages\n" |
| "-s addr --startaddress=addr Start address\n" |
| +"-x --skipleadingbad Skip leading bad blocks before startaddress\n" |
| "\n" |
| "--bb=METHOD, where METHOD can be `padbad', `dumpbad', or `skipbad':\n" |
| " padbad: dump flash data, substituting 0xFF for any bad blocks\n" |
| @@ -88,6 +89,7 @@ static const char *dumpfile; // dump file name |
| static bool quiet = false; // suppress diagnostic output |
| static bool canonical = false; // print nice + ascii |
| static bool forcebinary = false; // force printing binary to tty |
| +static bool skip_leading = false; // skip over leading bad blocks |
| |
| static enum { |
| padbad, // dump flash data, substituting 0xFF for any bad blocks |
| @@ -102,7 +104,7 @@ static void process_options(int argc, char * const argv[]) |
| |
| for (;;) { |
| int option_index = 0; |
| - static const char *short_options = "s:f:l:opqnca"; |
| + static const char *short_options = "s:f:l:opqncax"; |
| static const struct option long_options[] = { |
| {"help", no_argument, 0, 0}, |
| {"version", no_argument, 0, 0}, |
| @@ -114,6 +116,7 @@ static void process_options(int argc, char * const argv[]) |
| {"oob", no_argument, 0, 'o'}, |
| {"prettyprint", no_argument, 0, 'p'}, |
| {"startaddress", required_argument, 0, 's'}, |
| + {"skipleading", no_argument, 0, 'x'}, |
| {"length", required_argument, 0, 'l'}, |
| {"noecc", no_argument, 0, 'n'}, |
| {"quiet", no_argument, 0, 'q'}, |
| @@ -159,6 +162,9 @@ static void process_options(int argc, char * const argv[]) |
| case 's': |
| start_addr = simple_strtoll(optarg, &error); |
| break; |
| + case 'x': |
| + skip_leading = true; |
| + break; |
| case 'f': |
| if (!(dumpfile = strdup(optarg))) { |
| perror("stddup"); |
| @@ -392,7 +398,27 @@ int main(int argc, char * const argv[]) |
| start_addr, end_addr); |
| } |
| |
| + if (skip_leading) { |
| + if (!quiet) |
| + fprintf(stderr, "Skipping leading bad blocks.\n"); |
| + for (ofs = 0; ofs < start_addr && start_addr < mtd.size; ofs += mtd.eb_size) { |
| + if ((badblock = mtd_is_bad(&mtd, fd, ofs / mtd.eb_size)) < 0) { |
| + errmsg("libmtd: mtd_is_bad"); |
| + goto closeall; |
| + } |
| + if (badblock) { |
| + if (!quiet) |
| + fprintf(stderr, "block at 0x%08llx is bad, skipping.\n", ofs); |
| + start_addr = MIN(start_addr + mtd.eb_size, mtd.size); |
| + end_addr = MIN(end_addr + mtd.eb_size, mtd.size); |
| + } |
| + } |
| + } |
| /* Dump the flash contents */ |
| + if (!quiet) { |
| + fprintf(stderr, "startaddr: 0x%08llx .\n", start_addr); |
| + fprintf(stderr, " endaddr: 0x%08llx .\n", end_addr); |
| + } |
| for (ofs = start_addr; ofs < end_addr; ofs += bs) { |
| /* Check for bad block */ |
| if (bb_method == dumpbad) { |