Skip to contentSkip to conversation

mkcramfs changes to switch endianness

DISCUSSION Steven Hein 3 participants 6 messages May 2, 2001 – May 3, 2001

lore
Share & tools
lore
#0 lore raw

I'm getting ready to try using cramfs in the 2.4.4 kernel. Anybody done the work to make 'mkcramfs' create a big-endian
image on a little-endian PC? Before I reinvent the wheel,
I'd like to find out if anybody as done it (and would like
to share :)

Steve

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

#1 lore raw

cramfs is still endian dependant. Linus has a couple solutions to this problem, but last time I checked he wasn't clear which was the best. go for it and let us know how it turns out.

Quoted 9 lines · Steven Hein

I'm getting ready to try using cramfs in the 2.4.4 kernel. Anybody done the work to make 'mkcramfs' create a big-endian
image on a little-endian PC? Before I reinvent the wheel,
I'd like to find out if anybody as done it (and would like
to share :)

Steve

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

#2 lore raw
In reply to Steven Hein
Quoted 6 lines · Steven Hein

I'm getting ready to try using cramfs in the 2.4.4 kernel. Anybody done the work to make 'mkcramfs' create a big-endian
image on a little-endian PC? Before I reinvent the wheel,
I'd like to find out if anybody as done it (and would like
to share :)

I have the changes for the pre-midori mkcramfs. works fine but it is very ugly because of the use of bit fields. Have been running it for a few months and it does work fine :) We are in the process of integrating the latest changes from transmeta, but here is the patch for the old version.

Quoted 3 lines

Steve

cramfs/mkcramfs.c +54 -2
diff -u -r1.1 -r1.2
@@ -25,7 +25,7 @@
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: '%s dirname outfile'\n"
+	fprintf(stderr, "Usage: '%s [-e] dirname outfile'\n"
 		" where <dirname> is the root of the\n"
 		" filesystem to be compressed.\n", progname);
 	exit(1);
@@ -46,6 +46,7 @@
 static unsigned int blksize = PAGE_CACHE_SIZE;
 
 static int warn_dev, warn_gid, warn_namelen, warn_size, warn_uid;
+static int swap_endian;
 
 #ifndef MIN
 # define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
@@ -273,6 +274,39 @@
 	memset(area, 0x00, size);
 }
 
+static void fix_inode(struct cramfs_inode *inode)
+{
+#define wswap(x)    (((x)>>24) | (((x)>>8)&0xff00) | (((x)&0xff00)<<8) | (((x)&0xff)<<24))
+	/* attempt #2 */
+	inode->mode = (inode->mode >> 8) | ((inode->mode&0xff)<<8);
+	inode->uid = (inode->uid >> 8) | ((inode->uid&0xff)<<8);
+	inode->size = (inode->size >> 16) | (inode->size&0xff00) |
+		((inode->size&0xff)<<16);
+	((u32*)inode)[2] = wswap(inode->offset | (inode->namelen<<26));
+}
+
+static void fix_offset(struct cramfs_inode *inode, u32 offset)
+{
+	u32 tmp = wswap(((u32*)inode)[2]);
+	((u32*)inode)[2] = wswap((offset >> 2) | (tmp&0xfc000000));
+}
+
+static void fix_block_pointer(u32 *p)
+{
+	*p = wswap(*p);
+}
+
+static void fix_super(struct cramfs_super *super)
+{
+	u32 *p = (u32*)super;
+	p[0] = wswap(p[0]);	/* magic */
+	p[1] = wswap(p[1]);	/* size */
+	p[2] = wswap(p[2]);	/* flags */
+	p[3] = wswap(p[3]);	/* future */
+	fix_inode(&super->root);
+#undef wswap
+}
+
 /* Returns sizeof(struct cramfs_super), which includes the root inode. */
 static unsigned int write_superblock(struct entry *root, char *base)
 {
@@ -293,6 +327,7 @@
 	super->root.gid = root->gid;
 	super->root.size = root->size;
 	super->root.offset = offset >> 2;
+	if (swap_endian) fix_super(super);
 
 	return offset;
 }
@@ -305,7 +340,10 @@
 		fprintf(stderr, "filesystem too big.  Exiting.\n");
 		exit(1);
 	}
-	inode->offset = (offset >> 2);
+	if (swap_endian)
+		fix_offset(inode, offset);
+	else
+		inode->offset = (offset >> 2);
 }
 
 
@@ -360,6 +398,7 @@
 				stack_entries++;
 			}
 			entry = entry->next;
+			if (swap_endian) fix_inode(inode);
 		}
 
 		/*
@@ -452,6 +491,7 @@
 		}
 
 		*(u32 *) (base + offset) = curr;
+		if (swap_endian) fix_block_pointer((u32*)(base + offset));
 		offset += 4;
 	} while (size);
 
@@ -529,6 +569,18 @@
 
 	if (argc)
 		progname = argv[0];
+	while(argc > 1 && argv[1][0] == '-') {
+		switch(argv[1][1]) {
+		case 'e':
+			swap_endian = 1;
+			break;
+		default:
+			usage();
+			break;
+		}
+		argv++; argc--;
+	}
+
 	if (argc != 3)
 		usage();
 
author
#3 lore raw
Quoted 7 lines · David Blythe

I have the changes for the pre-midori mkcramfs. works fine but it is very ugly because of the use of bit fields. Have been running it for a few months and it does work fine :) We are in the process of integrating the latest changes from transmeta, but here is the patch for the old version.

THANKS for the patch!

Just out of curiousity, where do you get the source for the transmeta changes (their Midora Linux, I assume....). I went looking at their web site, and the FTP location they pointed to contained a midora-1.0.0-beta1*.tar.gz file that was only 36K.....where's the real thing?

Steve

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

#4 lore raw
Quoted 5 lines · Steve Hein

Just out of curiousity, where do you get the source for the transmeta changes (their Midora Linux, I assume....). I went looking at their web site, and the FTP location they pointed to contained a midora-1.0.0-beta1*.tar.gz file that was only 36K.....where's the real thing?

We used this, as a starting point (or one of the other references to this patch, i just did a google search to find it again).

http://lwn.net/2001/0118/a/cramfs.php3

I was hoping that it was all on sourceforge, but I guess not. We should finish integrating the endianness changes against this patch pretty soon. Maybe if someone else knows if there is a more up to date version around they could let us know.
david

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

#5 lore raw
Quoted 8 lines · David Blythe
Quoted 5 lines · Steve Hein

Just out of curiousity, where do you get the source for the transmeta changes (their Midora Linux, I assume....). I went looking at their web site, and the FTP location they pointed to contained a midora-1.0.0-beta1*.tar.gz file that was only 36K.....where's the real thing?

that file is just the build structure/files. once you install that you need to download the rest from the apps dir on the ftp site. start at
http://midori.sourceforge.net.

Quoted 5 lines

We used this, as a starting point (or one of the other references to this patch, i just did a google search to find it again).

http://lwn.net/2001/0118/a/cramfs.php3

That is the patch include with midori. If i remember correctly, it is included in the kernel mlz. mlz is the midori packaging method, basically a tar gz file.

Quoted 5 lines

I was hoping that it was all on sourceforge, but I guess not. We should finish integrating the endianness changes against this patch pretty soon. Maybe if someone else knows if there is a more up to date version around they could let us know.

it is all there on sourceforge, just need to dig a little:)

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/