mtd/util jffs2dump.c,1.1,1.2 Makefile,1.30,1.31

gleixner at infradead.org gleixner at infradead.org
Wed Apr 30 11:13:03 EDT 2003


Update of /home/cvs/mtd/util
In directory phoenix.infradead.org:/tmp/cvs-serv9114

Modified Files:
	jffs2dump.c Makefile 
Log Message:
Add bigendian support, add endianess conversion for fs images

Index: jffs2dump.c
===================================================================
RCS file: /home/cvs/mtd/util/jffs2dump.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- jffs2dump.c	8 Mar 2003 21:12:57 -0000	1.1
+++ jffs2dump.c	30 Apr 2003 15:13:00 -0000	1.2
@@ -29,14 +29,22 @@
 #include <sys/param.h>
 #include <asm/types.h>
 #include <dirent.h>
-#include "linux/jffs2.h"
+#include <linux/jffs2.h>
+#include <asm/byteorder.h>
 #include <getopt.h>
+#include "crc32.h"
 
 #define PROGRAM "jffs2dump"
 #define VERSION "1.0"
 
 #define PAD(x) (((x)+3)&~3)
 
+#define de32_to_cpu(x) (bigendian ? __be32_to_cpu(x.v32) : __le32_to_cpu(x.v32))
+#define de16_to_cpu(x) (bigendian ? __be16_to_cpu(x.v16) : __le16_to_cpu(x.v16))
+#define cnv_e32(x) ((jint32_t){(bigendian ? __be32_to_cpu(x.v32) : __le32_to_cpu(x.v32))})
+#define cnv_e16(x) ((jint16_t){(bigendian ? __be16_to_cpu(x.v16) : __le16_to_cpu(x.v16))})
+#define cpu_to_e32(x) ((jint32_t){(bigendian ? __cpu_to_le32(x) : __cpu_to_be32(x))})
+
 // Global variables
 long	imglen;		// length of image
 char	*data;		// image data
@@ -46,9 +54,13 @@
 	printf("Usage: dumpjffs2 [OPTION] INPUTFILE\n"
 	       "Dumps the contents of a binary JFFS2 image.\n"
 	       "\n"
-	       "      --help     	display this help and exit\n"
-	       "      --version  	output version information and exit\n"
-	       "-c    --content  	dump image contents\n");
+	       "           --help     	              display this help and exit\n"
+	       "           --version  	              output version information and exit\n"
+	       "-b         --bigendian	              image is bigendian\n"
+	       "-c         --content  	              dump image contents\n"
+	       "-e fname   --endianconvert=fname      convert image endianness, output to file fname\n"
+	       "-r         --recalccrc                recalc name and data crc on endian conversion\n" 	
+	       "-v         --verbose		      verbose output\n");
 	exit(0);
 }
 
@@ -69,9 +81,13 @@
 
 // Option variables
 
-int 	verbose;	// verbose output
-char 	*img;		// filename of image
-int	dumpcontent;	// dump image content
+int 	verbose;		// verbose output
+char 	*img;			// filename of image
+int	dumpcontent;		// dump image content
+int	bigendian;		// image is big endian
+int	convertendian;		// convert endianness
+int	recalccrc;		// recalc name and data crc's on endian conversion
+char	cnvfile[256];		// filename for conversion output
 
 void process_options (int argc, char *argv[])
 {
@@ -79,11 +95,14 @@
 
 	for (;;) {
 		int option_index = 0;
-		static const char *short_options = "cv";
+		static const char *short_options = "bce:rv";
 		static const struct option long_options[] = {
 			{"help", no_argument, 0, 0},
 			{"version", no_argument, 0, 0},
+			{"bigendian", no_argument, 0, 'b'},
 			{"content", no_argument, 0, 'c'},
+			{"endianconvert", required_argument, 0, 'e'},
+			{"recalccrc", required_argument, 0, 'r'},
 			{"verbose", no_argument, 0, 'v'},
 			{0, 0, 0, 0},
 		};
@@ -108,9 +127,19 @@
 		case 'v':
 			verbose = 1;
 			break;
+		case 'b':
+			bigendian = 1;
+			break;
 		case 'c':
 			dumpcontent = 1;
 			break;
+		case 'e':
+			convertendian = 1;
+			strcpy (cnvfile, optarg);
+			break;
+		case 'r':
+			recalccrc = 1;
+			break;
 		case '?':
 			error = 1;
 			break;
@@ -129,43 +158,101 @@
  */
 void do_dumpcontent (void) 
 {
-	char	*p = data;
-	union jffs2_node_union *node;
-	int	empty = 0, dirty = 0;
-	char	name[256];
+	char			*p = data;
+	union jffs2_node_union 	*node;
+	int			empty = 0, dirty = 0;
+	char			name[256];
+	uint32_t		crc;
 
 	while ( p < (data + imglen)) {
 		node = (union jffs2_node_union*) p;
+		
+		/* Skip empty space */
+		if (de16_to_cpu (node->u.magic) == 0xFFFF && de16_to_cpu (node->u.nodetype) == 0xFFFF) {
+			p += 4;
+			empty += 4;
+			continue;
+		}
+		
+		if (de16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK)	{
+			printf ("Wrong bitmask  at  0x%08x, 0x%04x\n", p - data, de16_to_cpu (node->u.magic));
+			p += 4;
+			dirty += 4;
+			continue;
+		}
+
+		crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4);
+		if (crc != de32_to_cpu (node->u.hdr_crc)) {
+			printf ("Wrong hdr_crc  at  0x%08x, 0x%08x instead of 0x%08x\n", p - data, de32_to_cpu (node->u.hdr_crc), crc);
+			p += 4;
+			dirty += 4;
+			continue;
+		}
 
-		switch(je16_to_cpu(node->u.nodetype)) {
+		switch(de16_to_cpu(node->u.nodetype)) {
+		
 		case JFFS2_NODETYPE_INODE:
 			printf ("Inode      node at 0x%08x, totlen 0x%08x, #ino  %5d, version %5d, isize %8d, csize %8d, dsize %8d, offset %8d\n",
-					p - data, je32_to_cpu (node->i.totlen), je32_to_cpu (node->i.ino),
-					je32_to_cpu ( node->i.version), je32_to_cpu (node->i.isize), 
-					je32_to_cpu (node->i.csize), je32_to_cpu (node->i.dsize), je32_to_cpu (node->i.offset));
-			p += PAD(je32_to_cpu (node->i.totlen));						
+					p - data, de32_to_cpu (node->i.totlen), de32_to_cpu (node->i.ino),
+					de32_to_cpu ( node->i.version), de32_to_cpu (node->i.isize), 
+					de32_to_cpu (node->i.csize), de32_to_cpu (node->i.dsize), de32_to_cpu (node->i.offset));
+
+			crc = crc32 (0, node, sizeof (struct jffs2_raw_inode) - 8);
+			if (crc != de32_to_cpu (node->i.node_crc)) {
+				printf ("Wrong node_crc at  0x%08x, 0x%08x instead of 0x%08x\n", p - data, de32_to_cpu (node->i.node_crc), crc);
+				p += PAD(de32_to_cpu (node->i.totlen));
+				dirty += PAD(de32_to_cpu (node->i.totlen));;
+				continue;
+			}
+			
+			crc = crc32(0, p + sizeof (struct jffs2_raw_inode), de32_to_cpu(node->i.csize));
+			if (crc != de32_to_cpu(node->i.data_crc)) {
+				printf ("Wrong data_crc at  0x%08x, 0x%08x instead of 0x%08x\n", p - data, de32_to_cpu (node->i.data_crc), crc);
+				p += PAD(de32_to_cpu (node->i.totlen));
+				dirty += PAD(de32_to_cpu (node->i.totlen));;
+				continue;
+			}
+
+			p += PAD(de32_to_cpu (node->i.totlen));
 			break;
 				
 		case JFFS2_NODETYPE_DIRENT:
 			memcpy (name, node->d.name, node->d.nsize);
 			name [node->d.nsize] = 0x0;
 			printf ("Dirent     node at 0x%08x, totlen 0x%08x, #pino %5d, version %5d, #ino  %8d, nsize %8d, name %s\n",
-					p - data, je32_to_cpu (node->d.totlen), je32_to_cpu (node->d.pino),
-					je32_to_cpu ( node->d.version), je32_to_cpu (node->d.ino), 
+					p - data, de32_to_cpu (node->d.totlen), de32_to_cpu (node->d.pino),
+					de32_to_cpu ( node->d.version), de32_to_cpu (node->d.ino), 
 					node->d.nsize, name);
-			p += PAD(je32_to_cpu (node->d.totlen));						
+
+			crc = crc32 (0, node, sizeof (struct jffs2_raw_dirent) - 8);
+			if (crc != de32_to_cpu (node->d.node_crc)) {
+				printf ("Wrong node_crc at  0x%08x, 0x%08x instead of 0x%08x\n", p - data, de32_to_cpu (node->d.node_crc), crc);
+				p += PAD(de32_to_cpu (node->d.totlen));
+				dirty += PAD(de32_to_cpu (node->d.totlen));;
+				continue;
+			}
+			
+			crc = crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize);
+			if (crc != de32_to_cpu(node->d.name_crc)) {
+				printf ("Wrong name_crc at  0x%08x, 0x%08x instead of 0x%08x\n", p - data, de32_to_cpu (node->d.name_crc), crc);
+				p += PAD(de32_to_cpu (node->d.totlen));
+				dirty += PAD(de32_to_cpu (node->d.totlen));;
+				continue;
+			}
+
+			p += PAD(de32_to_cpu (node->d.totlen));						
 			break;
 	
 		case JFFS2_NODETYPE_CLEANMARKER:
 			if (verbose)
-				printf ("Cleanmarker     at 0x%08x, totlen 0x%08x\n", p - data, je32_to_cpu (node->u.totlen));
-			p += PAD(je32_to_cpu (node->u.totlen));						
+				printf ("Cleanmarker     at 0x%08x, totlen 0x%08x\n", p - data, de32_to_cpu (node->u.totlen));
+			p += PAD(de32_to_cpu (node->u.totlen));						
 			break;
 	
 		case JFFS2_NODETYPE_PADDING:
 			if (verbose)
-				printf ("Padding    node at 0x%08x, totlen 0x%08x\n", p - data, je32_to_cpu (node->u.totlen));
-			p += PAD(je32_to_cpu (node->u.totlen));						
+				printf ("Padding    node at 0x%08x, totlen 0x%08x\n", p - data, de32_to_cpu (node->u.totlen));
+			p += PAD(de32_to_cpu (node->u.totlen));						
 			break;
 			
 		case 0xffff:
@@ -175,9 +262,9 @@
 			
 		default:	
 			if (verbose)
-				printf ("Unknown    node at 0x%08x, totlen 0x%08x\n", p - data, je32_to_cpu (node->u.totlen));
-			p += PAD(je32_to_cpu (node->u.totlen));						
-			dirty += PAD(je32_to_cpu (node->u.totlen));						
+				printf ("Unknown    node at 0x%08x, totlen 0x%08x\n", p - data, de32_to_cpu (node->u.totlen));
+			p += PAD(de32_to_cpu (node->u.totlen));						
+			dirty += PAD(de32_to_cpu (node->u.totlen));						
 	
 		}
 	}
@@ -185,6 +272,141 @@
 	if (verbose)
 		printf ("Empty space: %d, dirty space: %d\n", empty, dirty);
 }
+
+/*
+ *	Convert endianess
+ */
+void do_endianconvert (void) 
+{
+	char			*p = data;
+	union jffs2_node_union 	*node, newnode;
+	int			fd, len;
+	jint32_t		mode;
+	uint32_t		crc;
+	
+	fd = open (cnvfile, O_WRONLY | O_CREAT, 0644);
+	if (fd < 0) {
+		fprintf (stderr, "Cannot open / create file: %s\n", cnvfile);
+		return;
+	}	
+
+	while ( p < (data + imglen)) {
+		node = (union jffs2_node_union*) p;
+
+		/* Skip empty space */
+		if (de16_to_cpu (node->u.magic) == 0xFFFF && de16_to_cpu (node->u.nodetype) == 0xFFFF) {
+			write (fd, p, 4);
+			p += 4;
+			continue;
+		}
+		
+		if (de16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK)	{
+			printf ("Wrong bitmask  at  0x%08x, 0x%04x\n", p - data, de16_to_cpu (node->u.magic));
+			newnode.u.magic = cnv_e16 (node->u.magic);			
+			newnode.u.nodetype = cnv_e16 (node->u.nodetype);
+			write (fd, &newnode, 4);
+			p += 4;
+			continue;
+		}
+
+		crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4);
+		if (crc != de32_to_cpu (node->u.hdr_crc)) {
+			printf ("Wrong hdr_crc  at  0x%08x, 0x%08x instead of 0x%08x\n", p - data, de32_to_cpu (node->u.hdr_crc), crc);
+		}
+
+		switch(de16_to_cpu(node->u.nodetype)) {
+
+		case JFFS2_NODETYPE_INODE:
+
+			newnode.i.magic = cnv_e16 (node->i.magic);			
+			newnode.i.nodetype = cnv_e16 (node->i.nodetype);
+			newnode.i.totlen = cnv_e32 (node->i.totlen);
+			newnode.i.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
+			newnode.i.ino = cnv_e32 (node->i.ino);
+			newnode.i.version = cnv_e32 (node->i.version);
+			mode.v32 = node->i.mode.m;
+			mode = cnv_e32 (mode);
+			newnode.i.mode.m = mode.v32;
+			newnode.i.uid = cnv_e16 (node->i.uid);
+			newnode.i.gid = cnv_e16 (node->i.gid);
+			newnode.i.isize = cnv_e32 (node->i.isize);
+			newnode.i.atime = cnv_e32 (node->i.atime);
+			newnode.i.mtime = cnv_e32 (node->i.mtime);
+			newnode.i.ctime = cnv_e32 (node->i.ctime);
+			newnode.i.offset = cnv_e32 (node->i.offset);
+			newnode.i.csize = cnv_e32 (node->i.csize);
+			newnode.i.dsize = cnv_e32 (node->i.dsize);
+			newnode.i.compr = node->i.compr;
+			newnode.i.usercompr = node->i.usercompr;
+			newnode.i.flags = cnv_e16 (node->i.flags);
+			if (recalccrc) {
+				len = de32_to_cpu(node->i.csize);
+				newnode.i.data_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_inode), len));
+			} else
+				newnode.i.data_crc = cnv_e32 (node->i.data_crc);
+			
+			newnode.i.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_inode) - 8));
+			
+			write (fd, &newnode, sizeof (struct jffs2_raw_inode));
+			write (fd, p + sizeof (struct jffs2_raw_inode), PAD (de32_to_cpu (node->i.totlen) -  sizeof (struct jffs2_raw_inode)));
+
+			p += PAD(de32_to_cpu (node->i.totlen));						
+			break;
+				
+		case JFFS2_NODETYPE_DIRENT:
+			newnode.d.magic = cnv_e16 (node->d.magic);
+			newnode.d.nodetype = cnv_e16 (node->d.nodetype);
+			newnode.d.totlen = cnv_e32 (node->d.totlen);
+			newnode.d.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
+			newnode.d.pino = cnv_e32 (node->d.pino);
+			newnode.d.version = cnv_e32 (node->d.version);
+			newnode.d.ino = cnv_e32 (node->d.ino);
+			newnode.d.mctime = cnv_e32 (node->d.mctime);
+			newnode.d.nsize = node->d.nsize;
+			newnode.d.type = node->d.type;
+			newnode.d.unused[0] = node->d.unused[0];
+			newnode.d.unused[1] = node->d.unused[1];
+			newnode.d.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_dirent) - 8));
+			if (recalccrc)
+				newnode.d.name_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize));
+			else
+				newnode.d.name_crc = cnv_e32 (node->d.name_crc);
+
+			write (fd, &newnode, sizeof (struct jffs2_raw_dirent));
+			write (fd, p + sizeof (struct jffs2_raw_dirent), PAD (de32_to_cpu (node->d.totlen) -  sizeof (struct jffs2_raw_dirent)));
+			p += PAD(de32_to_cpu (node->d.totlen));						
+			break;
+	
+		case JFFS2_NODETYPE_CLEANMARKER:
+		case JFFS2_NODETYPE_PADDING:
+			newnode.u.magic = cnv_e16 (node->u.magic);
+			newnode.u.nodetype = cnv_e16 (node->u.nodetype);
+			newnode.u.totlen = cnv_e32 (node->u.totlen);
+			newnode.u.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4));
+			
+			write (fd, &newnode, sizeof (struct jffs2_unknown_node));
+			len = PAD(de32_to_cpu (node->u.totlen) - sizeof (struct jffs2_unknown_node));
+			if (len > 0) 
+				write (fd, p + sizeof (struct jffs2_unknown_node), len);
+				
+			p += PAD(de32_to_cpu (node->u.totlen));						
+			break;
+	
+		case 0xffff:
+			write (fd, p, 4);
+			p += 4;
+			break;
+			
+		default:	
+			printf ("Unknown node type: 0x%04x at 0x%08x, totlen 0x%08x\n", de16_to_cpu (node->u.nodetype), p - data, de32_to_cpu (node->u.totlen));
+			p += PAD(de32_to_cpu (node->u.totlen));
+				
+		}
+	}
+
+	close (fd);
+
+}
 	
 /*
  * Main program
@@ -221,6 +443,8 @@
 	if (dumpcontent)
 		do_dumpcontent ();
 
+	if (convertendian)
+		do_endianconvert ();
 	
 	// free memory
 	free (data);

Index: Makefile
===================================================================
RCS file: /home/cvs/mtd/util/Makefile,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- Makefile	8 Mar 2003 21:13:26 -0000	1.30
+++ Makefile	30 Apr 2003 15:13:00 -0000	1.31
@@ -3,7 +3,7 @@
 
 # $Id$
 
-# CROSS=arm-linux-
+#CROSS=arm-linux-
 CC := $(CROSS)gcc
 CFLAGS += -I../include -O2 -Wall -Wstrict-prototypes -Wshadow
 
@@ -32,4 +32,6 @@
 jffs2reader: jffs2reader.o
 	$(CC) $(LDFLAGS) -o $@ $^ -lz 
 
+jffs2dump: jffs2dump.o crc32.o
+	$(CC) $(LDFLAGS) -o $@ $^
 




More information about the linux-mtd-cvs mailing list