From 559e45026b84273e17da408e0fbe468e1f6ac5ea Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 14 Nov 2013 19:04:44 +0000
Subject: padjffs2: add a different kind of padding (using standard jffs2
 elements) to work around broken boot loaders for kernel partitions

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@38804 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 tools/padjffs2/src/padjffs2.c | 66 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 17 deletions(-)

(limited to 'tools/padjffs2')

diff --git a/tools/padjffs2/src/padjffs2.c b/tools/padjffs2/src/padjffs2.c
index aa932efa6f..59c7625dc4 100644
--- a/tools/padjffs2/src/padjffs2.c
+++ b/tools/padjffs2/src/padjffs2.c
@@ -21,6 +21,10 @@
 static char *progname;
 static unsigned int xtra_offset;
 static unsigned char eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
+static unsigned char jffs2_pad_be[] = "\x19\x85\x20\x04\x04\x00\x00\x00\xc4\x94\xdb\xf4";
+static unsigned char jffs2_pad_le[] = "\x85\x19\x04\x20\x00\x00\x00\x04\xa8\xfb\xa0\xb4";
+static unsigned char *pad = eof_mark;
+static int pad_len = sizeof(eof_mark);
 
 #define ERR(fmt, ...) do { \
 	fflush(0); \
@@ -105,12 +109,12 @@ static int pad_image(char *name, uint32_t pad_mask)
 		}
 
 		/* write out the JFFS end-of-filesystem marker */
-		t = write(fd, eof_mark, 4);
-		if (t != 4) {
+		t = write(fd, pad, pad_len);
+		if (t != pad_len) {
 			ERRS("Unable to write to %s", name);
 			goto close;
 		}
-		out_len += 4;
+		out_len += pad_len;
 	}
 
 	ret = 0;
@@ -123,39 +127,67 @@ out:
 	return ret;
 }
 
+static int usage(void)
+{
+	fprintf(stderr,
+		"Usage: %s file [<options>] [pad0] [pad1] [padN]\n"
+		"Options:\n"
+		"  -x <offset>:          Add an extra offset for padding data\n"
+		"  -J:                   Use a fake big-endian jffs2 padding element instead of EOF\n"
+		"                        This is used to work around broken boot loaders that\n"
+		"                        try to parse the entire firmware area as one big jffs2\n"
+		"  -j:                   (like -J, but little-endian instead of big-endian)\n"
+		"\n",
+		progname);
+	return EXIT_FAILURE;
+}
+
 int main(int argc, char* argv[])
 {
+	char *image;
 	uint32_t pad_mask;
 	int ret = EXIT_FAILURE;
 	int err;
-	int i;
+	int ch, i;
 
 	progname = basename(argv[0]);
 
-	if (argc < 2) {
-		fprintf(stderr,
-			"Usage: %s file [-x <xtra offset>] [pad0] [pad1] [padN]\n",
-			progname);
-		goto out;
-	}
+	if (argc < 2)
+		return usage();
+
+	image = argv[1];
+	argv++;
+	argc--;
 
 	pad_mask = 0;
-	for (i = 2; i < argc; i++) {
-		if (i == 2 && strcmp(argv[i], "-x") == 0) {
-			i++;
-			xtra_offset = strtoul(argv[i], NULL, 0);
+	while ((ch = getopt(argc, argv, "x:Jj")) != -1) {
+		switch (ch) {
+		case 'x':
+			xtra_offset = strtoul(optarg, NULL, 0);
 			fprintf(stderr, "assuming %u bytes offset\n",
 				xtra_offset);
-			continue;
+			break;
+		case 'J':
+			pad = jffs2_pad_be;
+			pad_len = sizeof(jffs2_pad_be) - 1;
+			break;
+		case 'j':
+			pad = jffs2_pad_le;
+			pad_len = sizeof(jffs2_pad_le) - 1;
+			break;
+		default:
+			return usage();
 		}
-		pad_mask |= strtoul(argv[i], NULL, 0) * 1024;
 	}
 
+	for (i = optind; i < argc; i++)
+		pad_mask |= strtoul(argv[i], NULL, 0) * 1024;
+
 	if (pad_mask == 0)
 		pad_mask = (4 * 1024) | (8 * 1024) | (64 * 1024) |
 			   (128 * 1024);
 
-	err = pad_image(argv[1], pad_mask);
+	err = pad_image(image, pad_mask);
 	if (err)
 		goto out;
 
-- 
cgit v1.2.3