blob: b503ab5b6841238ba561d4e93e0fdf36801a5714 [file] [log] [blame]
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) {