mtd/util nanddump.c,1.18,1.19
gleixner at infradead.org
gleixner at infradead.org
Fri Oct 1 16:16:05 EDT 2004
Update of /home/cvs/mtd/util
In directory phoenix.infradead.org:/tmp/cvs-serv7135
Modified Files:
nanddump.c
Log Message:
make interface usable, make dump without oob possible
Index: nanddump.c
===================================================================
RCS file: /home/cvs/mtd/util/nanddump.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- nanddump.c 12 Sep 2004 09:36:06 -0000 1.18
+++ nanddump.c 1 Oct 2004 20:16:02 -0000 1.19
@@ -12,8 +12,7 @@
*
* Overview:
* This utility dumps the contents of raw NAND chips or NAND
- * chips contained in DoC devices. NOTE: If you are using raw
- * NAND chips, disable NAND ECC in your kernel.
+ * chips contained in DoC devices.
*/
#define _GNU_SOURCE
@@ -23,6 +22,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <getopt.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -30,6 +30,114 @@
#include <asm/types.h>
#include <mtd/mtd-user.h>
+#define PROGRAM "nanddump"
+#define VERSION "V 1.19"
+
+void display_help (void)
+{
+ printf("Usage: nanddump [OPTIONS] MTD-device\n"
+ "Dumps the contents of a nand mtd partition.\n"
+ "\n"
+ " --help display this help and exit\n"
+ " --version output version information and exit\n"
+ "-f file --file=file dump to file\n"
+ "-i --ignoreerrors ignore errors\n"
+ "-l length --length=length length\n"
+ "-o --omitoob omit oob data\n"
+ "-p --prettyprint print nice (hexdump)\n"
+ "-s addr --startaddress=addr start address\n");
+ exit(0);
+}
+
+void display_version (void)
+{
+ printf(PROGRAM " " VERSION "\n"
+ "\n"
+ PROGRAM " comes with NO WARRANTY\n"
+ "to the extent permitted by law.\n"
+ "\n"
+ "You may redistribute copies of " PROGRAM "\n"
+ "under the terms of the GNU General Public Licence.\n"
+ "See the file `COPYING' for more information.\n");
+ exit(0);
+}
+
+// Option variables
+
+int ignoreerrors; // ignore errors
+int pretty_print; // print nice in ascii
+int omitoob; // omit oob data
+unsigned long start_addr; // start address
+unsigned long length; // dump length
+char *mtddev; // mtd device name
+char *dumpfile; // dump file name
+
+
+void process_options (int argc, char *argv[])
+{
+ int error = 0;
+
+ for (;;) {
+ int option_index = 0;
+ static const char *short_options = "a:f:il:op";
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 0},
+ {"version", no_argument, 0, 0},
+ {"ignoreerrors", no_argument, 0, 'i'},
+ {"prettyprint", no_argument, 0, 'p'},
+ {"omitoob", no_argument, 0, 'o'},
+ {"start", required_argument, 0, 'a'},
+ {"length", required_argument, 0, 'l'},
+ {0, 0, 0, 0},
+ };
+
+ int c = getopt_long(argc, argv, short_options,
+ long_options, &option_index);
+ if (c == EOF) {
+ break;
+ }
+
+ switch (c) {
+ case 0:
+ switch (option_index) {
+ case 0:
+ display_help();
+ break;
+ case 1:
+ display_version();
+ break;
+ }
+ break;
+ case 'a':
+ start_addr = atol(optarg);
+ break;
+ case 'f':
+ dumpfile = argv[optind];
+ break;
+ case 'i':
+ ignoreerrors = 1;
+ break;
+ case 'l':
+ length = atol(optarg);
+ break;
+ case 'o':
+ omitoob = 1;
+ break;
+ case 'p':
+ pretty_print = 1;
+ break;
+ case '?':
+ error = 1;
+ break;
+ }
+ }
+
+ if ((argc - optind) != 1 || error)
+ display_help ();
+
+ mtddev = argv[optind];
+}
+
/*
* Buffers for reading data from flash
*/
@@ -41,21 +149,16 @@
*/
int main(int argc, char **argv)
{
- unsigned long ofs;
- int i, fd, ofd, bs, start_addr, end_addr, pretty_print;
+ unsigned long ofs, blockstart = 1, end_addr = 0;
+ int i, fd, ofd, bs, badblock = 0;
struct mtd_oob_buf oob = {0, 16, oobbuf};
mtd_info_t meminfo;
unsigned char pretty_buf[80];
- /* Make sure enough arguments were passed */
- if (argc < 3) {
- fprintf(stdout, "nanddump V1.18");
- fprintf(stderr, "usage: <mtdname> <dumpname> [start addr] [length]\n");
- exit(1);
- }
+ process_options(argc, argv);
/* Open MTD device */
- if ((fd = open(argv[1], O_RDONLY)) == -1) {
+ if ((fd = open(mtddev, O_RDONLY)) == -1) {
perror("open flash");
exit (1);
}
@@ -79,50 +182,48 @@
oob.length = meminfo.oobsize;
/* Open output file for writing. If file name is "-", write to standard output. */
- if (strcmp(argv[2], "-") == 0) {
+ if (!dumpfile) {
ofd = STDOUT_FILENO;
- } else if ((ofd = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0644)) == -1) {
+ } else if ((ofd = open(dumpfile, O_WRONLY | O_TRUNC | O_CREAT, 0644)) == -1) {
perror ("open outfile");
close(fd);
exit(1);
}
/* Initialize start/end addresses and block size */
- start_addr = 0;
- end_addr = meminfo.size;
- bs = meminfo.oobblock;
+ if (length)
+ end_addr = start_addr + length;
+ if (!length || end_addr > meminfo.size)
+ end_addr = meminfo.size;
- /* See if start address and length were specified */
- if (argc == 4) {
- start_addr = strtoul(argv[3], NULL, 0) & ~(bs - 1);
- end_addr = meminfo.size;
- } else if (argc == 5) {
- start_addr = strtoul(argv[3], NULL, 0) & ~(bs - 1);
- end_addr = (strtoul(argv[3], NULL, 0) + strtoul(argv[4], NULL, 0)) & ~(bs - 1);
- }
-
- /* Ask user if they would like pretty output */
- fprintf(stderr, "Would you like formatted output? ");
- if (tolower(getc(stdin)) != 'y')
- pretty_print = 0;
- else
- pretty_print = 1;
+ bs = meminfo.oobblock;
/* Print informative message */
fprintf(stderr, "Dumping data starting at 0x%08x and ending at 0x%08x...\n",
- start_addr, end_addr);
+ (unsigned int) start_addr, (unsigned int) end_addr);
/* Dump the flash contents */
for (ofs = start_addr; ofs < end_addr ; ofs+=bs) {
- /* Read page data and exit on failure */
- if (pread(fd, readbuf, bs, ofs) != bs) {
- perror("pread");
- close(fd);
- close(ofd);
- exit(1);
+ // new eraseblock , check for bad block
+ if (blockstart != (ofs & (~meminfo.erasesize + 1))) {
+ blockstart = ofs & (~meminfo.erasesize + 1);
+ if ((badblock = ioctl(fd, MEMGETBADBLOCK, &blockstart)) < 0) {
+ perror("ioctl(MEMGETBADBLOCK)");
+ goto closeall;
+ }
}
+ if (badblock) {
+ memset (readbuf, 0xff, bs);
+ } else {
+ /* Read page data and exit on failure */
+ if (pread(fd, readbuf, bs, ofs) != bs) {
+ perror("pread");
+ goto closeall;
+ }
+ }
+
/* Write out page data */
if (pretty_print) {
for (i = 0; i < bs; i += 16) {
@@ -143,18 +244,22 @@
} else
write(ofd, readbuf, bs);
- /* Read OOB data and exit on failure */
- oob.start = ofs;
- if (ioctl(fd, MEMREADOOB, &oob) != 0) {
- perror("ioctl(MEMREADOOB)");
- close(fd);
- close(ofd);
- exit(1);
+ if (omitoob)
+ continue;
+
+ if (badblock) {
+ memset (readbuf, 0xff, meminfo.oobsize);
+ } else {
+ /* Read OOB data and exit on failure */
+ oob.start = ofs;
+ if (ioctl(fd, MEMREADOOB, &oob) != 0) {
+ perror("ioctl(MEMREADOOB)");
+ goto closeall;
+ }
}
/* Write out OOB data */
if (pretty_print) {
-
if (meminfo.oobsize < 16) {
sprintf(pretty_buf, " OOB Data: %02x %02x %02x %02x %02x %02x "
"%02x %02x\n",
@@ -186,4 +291,10 @@
/* Exit happy */
return 0;
+
+ closeall:
+ close(fd);
+ close(ofd);
+ exit(1);
+
}
More information about the linux-mtd-cvs
mailing list