cramfs for root filesystem?

Stephen Cameron steve.cameron at hp.com
Wed Jun 26 02:04:21 EST 2002


I have tried to fix up the endian-swapping patch for
the mkcramfs from sourceforge CVS, circa Mon Jun 24, 2002
:pserver:anonymous at cvs.cramfs.sourceforge.net:/cvsroot/cramfs

No guarantees, of course, use at your own risk.

Currently, I get as far as trying to start init with this
patch, (the same filesystem via NFS works fine.)  This
may be due to the fact that I haven't touched the kernel
code, (that is, I have not allowed for ramdisk to handle
4k block size, as I've been led to believe I must.)

Here's what I'm seeing when I try to use my rootfs
(not that it's necessarily relevant, but I don't
want to imply that I know my patch is perfect):

	RAMDISK: Compressed image found at block 0
	Freeing initrd memory: 1270k freed
	VFS: Mounted root (cramfs filesystem) readonly.
	Freeing unused kernel memory: 196k init
	Warning: unable to open an initial console.
	Kernel panic: No init found.  Try passing init= option to kernel.
	<0>Rebooting in 180 seconds..

-- steve

And here's the patch:

diff -u -r1.1.1.1 mkcramfs.c
--- mkcramfs.c	24 Jun 2002 19:22:19 -0000	1.1.1.1
+++ mkcramfs.c	25 Jun 2002 15:56:42 -0000
@@ -95,6 +95,7 @@
 static char *opt_name = NULL;

 static int warn_dev, warn_gid, warn_namelen, warn_skip, warn_size, warn_uid;
+static int swap_endian = 0;

 /* In-core version of inode / directory entry. */
 struct entry {
@@ -130,6 +131,7 @@
 		" -i file    insert a file image into the filesystem (requires >= 2.4.0)\n"
 		" -n name    set name of cramfs filesystem\n"
 		" -p         pad by %d bytes for boot code\n"
+		" -r         reverse endianness of filesystem\n"
 		" -s         sort directory entries (old option, ignored)\n"
 		" -v         be more verbose\n"
 		" -z         make explicit holes (requires >= 2.3.39)\n"
@@ -372,6 +374,58 @@
 	return totalsize;
 }

+#define wswap(x)	(((x)>>24) | (((x)>>8)&0xff00) | \
+			(((x)&0xff00)<<8) | (((x)&0xff)<<24))
+
+/* routines to swap endianness/bitfields in inode/superblock block data */
+static void fix_inode(struct cramfs_inode *inode)
+{
+	if (!swap_endian) return;
+	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;
+	if (!swap_endian) return;
+	tmp = wswap(((u32*)inode)[2]);
+	((u32*)inode)[2] = wswap((offset >> 2) | (tmp&0xfc000000));
+}
+
+static void fix_block_pointer(u32 *p)
+{
+	if (!swap_endian) return;
+	*p = wswap(*p);
+}
+
+static void fix_super(struct cramfs_super *super)
+{
+	u32 *p = (u32*)super;
+
+	if (!swap_endian) return;
+
+	/* fix superblock fields */
+	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 filesystem info fields */
+	p = (u32*)&super->fsid;
+	p[0] = wswap(p[0]); /* crc */
+	p[1] = wswap(p[1]); /* edition */
+	p[2] = wswap(p[2]); /* blocks */
+	p[3] = wswap(p[3]); /* files */
+
+	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, int size)
 {
@@ -405,7 +459,9 @@
 	super->root.uid = CRAMFS_16(root->uid);
 	super->root.gid = root->gid;
 	super->root.size = CRAMFS_24(root->size);
+	fix_super(super);
 	CRAMFS_SET_OFFSET(&(super->root), offset >> 2);
+	fix_offset(&(super->root), offset);

 	return offset;
 }
@@ -421,6 +477,7 @@
 		die(MKFS_ERROR, 0, "filesystem too big");
 	}
 	CRAMFS_SET_OFFSET(inode, offset >> 2);
+	fix_offset(inode, offset);
 }

 /*
@@ -610,6 +667,7 @@
 		}

 		*(u32 *) (base + offset) = CRAMFS_32(curr);
+		fix_block_pointer((u32*)(base + offset));
 		offset += 4;
 	} while (size);

@@ -700,7 +758,7 @@
 		progname = argv[0];

 	/* command line options */
-	while ((c = getopt(argc, argv, "hEe:i:n:psvz")) != EOF) {
+	while ((c = getopt(argc, argv, "hEe:i:n:prsvz")) != EOF) {
 		switch (c) {
 		case 'h':
 			usage(MKFS_OK);
@@ -727,6 +785,10 @@
 		case 'p':
 			opt_pad = PAD_SIZE;
 			fslen_ub += PAD_SIZE;
+			break;
+		case 'r':
+			swap_endian = 1;
+			fprintf(stderr, "Swapping filesystem endianness.\n");
 			break;
 		case 's':
 			/* old option, ignored */

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





More information about the Linuxppc-embedded mailing list