diff options
-rw-r--r-- | nanddump.c | 38 |
1 files changed, 36 insertions, 2 deletions
@@ -50,6 +50,7 @@ static void display_help(void) "-a --forcebinary Force printing of binary data to tty\n" "-c --canonicalprint Print canonical Hex+ASCII dump\n" "-f file --file=file Dump to file\n" +"-k --skipbad Skip over bad blocks (see below)\n" "-l length --length=length Length\n" "-n --noecc Read without error correction\n" "-N --noskipbad Read without bad block skipping\n" @@ -57,7 +58,14 @@ static void display_help(void) "-b --omitbad Omit bad blocks from the dump\n" "-p --prettyprint Print nice (hexdump)\n" "-q --quiet Don't display progress and status messages\n" -"-s addr --startaddress=addr Start address\n", +"-s addr --startaddress=addr Start address\n" +"\n" +"Notes on --omitbad and --skipbad:\n" +" With either option, we stop dumping data when we encounter a bad block\n" +" and resume dumping at the next good block. However, with --omitbad, we\n" +" count the bad block as part of the total dump length, whereas with\n" +" --skipbad, the bad block is 'skipped,' that is, not counted toward the\n" +" total dump length.\n", PROGRAM_NAME); exit(EXIT_SUCCESS); } @@ -90,6 +98,7 @@ static bool omitbad = false; 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 skipbad = false; // skip over bad blocks static void process_options(int argc, char * const argv[]) { @@ -97,7 +106,7 @@ static void process_options(int argc, char * const argv[]) for (;;) { int option_index = 0; - static const char *short_options = "bs:f:l:opqnNca"; + static const char *short_options = "bs:f:l:opqnNcak"; static const struct option long_options[] = { {"help", no_argument, 0, 0}, {"version", no_argument, 0, 0}, @@ -111,6 +120,7 @@ static void process_options(int argc, char * const argv[]) {"length", required_argument, 0, 'l'}, {"noecc", no_argument, 0, 'n'}, {"noskipbad", no_argument, 0, 'N'}, + {"skipbad", no_argument, 0, 'k'}, {"quiet", no_argument, 0, 'q'}, {0, 0, 0, 0}, }; @@ -167,6 +177,9 @@ static void process_options(int argc, char * const argv[]) case 'N': noskipbad = true; break; + case 'k': + skipbad = true; + break; case '?': error++; break; @@ -193,6 +206,19 @@ static void process_options(int argc, char * const argv[]) exit(EXIT_FAILURE); } + if (noskipbad && skipbad) { + fprintf(stderr, "The noskipbad and skipbad options are " + "mutually-exclusive.\n" + "Choose one or the other.\n"); + exit(EXIT_FAILURE); + } + + if (omitbad && skipbad) { + fprintf(stderr, "The omitbad and skipbad options are mutually-" + "exclusive.\nChoose one or the other.\n"); + exit(EXIT_FAILURE); + } + if ((argc - optind) != 1 || error) display_help(); @@ -403,6 +429,14 @@ int main(int argc, char * const argv[]) } if (badblock) { + /* skip bad block, increase end_addr */ + if (skipbad) { + end_addr += mtd.eb_size; + ofs += mtd.eb_size - bs; + if (end_addr > mtd.size) + end_addr = mtd.size; + continue; + } if (omitbad) continue; memset(readbuf, 0xff, bs); |