--- linux/init/initramfs.c.orig 2012-12-05 21:39:09.000000000 -0500 +++ linux/init/initramfs.c 2012-12-10 12:15:49.000000000 -0500 @@ -569,14 +569,56 @@ } #endif +static char * __initdata ramdisk_size; + +static int __init rdsize_setup(char *str) +{ + ramdisk_size = str; + return 1; +} +__setup("rdsize=", rdsize_setup); + +static int __init change_root_to_tmpfs(void) +{ + char size[38], *s; + + sprintf(size, "size=%.20s,nr_inodes=0", ramdisk_size); + if ((s = strchr(size, ','))) + *s = '\0'; + + if (!sys_mkdir("/root", 0700) && + !sys_mount("/dev/root", "/root", "tmpfs", 0, size) && + !sys_chdir("/root") && + !sys_mount(".", "/", NULL, MS_MOVE, NULL) && + !sys_chroot(".")) + return 0; + + panic("Failed to mount tmpfs as root filesystem"); +} + + static int __init populate_rootfs(void) { - char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size); + char *err; + + if (ramdisk_size) + change_root_to_tmpfs(); + + err = unpack_to_rootfs(__initramfs_start, __initramfs_size); if (err) panic(err); /* Failed to decompress INTERNAL initramfs */ if (initrd_start) { #ifdef CONFIG_BLK_DEV_RAM int fd; + if (ramdisk_size) { + printk(KERN_INFO "Unpacking initramfs...\n"); + err = unpack_to_rootfs((char *)initrd_start, + initrd_end - initrd_start); + if (err) + panic(err); + free_initrd(); + return 0; + } printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n"); err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start);