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