diff -u linux-2.6.16.29-orig/init/do_mounts.c linux-2.6.16.29/init/do_mounts.c --- linux-2.6.16.29-orig/init/do_mounts.c 2006-09-12 20:02:10.000000000 +0200 +++ linux-2.6.16.29/init/do_mounts.c 2006-09-23 19:48:57.986439236 +0200 @@ -16,6 +16,7 @@ #include "do_mounts.h" extern int get_filesystem_list(char * buf); +extern int populate_rootfs(int); int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ @@ -412,6 +413,11 @@ is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; +#ifdef CONFIG_INIT_TMPFS + if (populate_rootfs(0)) + goto out; +#endif + if (initrd_load()) goto out; diff -u linux-2.6.16.29-orig/init/initramfs.c linux-2.6.16.29/init/initramfs.c --- linux-2.6.16.29-orig/init/initramfs.c 2006-09-12 20:02:10.000000000 +0200 +++ linux-2.6.16.29/init/initramfs.c 2006-09-23 19:59:17.379743943 +0200 @@ -498,24 +498,86 @@ #endif -void __init populate_rootfs(void) +#ifdef CONFIG_INIT_TMPFS +static char __initdata tmpfs_options[64] = "mode=755"; /* options passed to tmpfs */ +int __init mount_tmpfs_root(void); +extern int root_mountflags; + +static int __init inittmpfs_options(char *str) +{ + strncpy(tmpfs_options,str,63); + tmpfs_options[63] = 0; + return 1; +} + +__setup("inittmpfs=", inittmpfs_options); + +/* + * Mount a root tmpfs. Return 0 on success; -1 on failure. + */ +int init_tmpfs (void); +int __init mount_tmpfs_root(void) { - char *err = unpack_to_rootfs(__initramfs_start, - __initramfs_end - __initramfs_start, 0); - if (err) - panic(err); + int err; + int tmpfs_root_mountflags = root_mountflags; + + /* create mount point */ + if ( (err = sys_mkdir("/tmp_root", 0755)) < 0) { + printk(KERN_ERR "INITRAMFS: unable to create mountpoint /tmp_root. (%d)\n", err); + return -1; + } + + printk ("INITRAMFS: Trying to mount tmpfs using options '%s'.\n", tmpfs_options); + /* always mount rw,verbose */ + tmpfs_root_mountflags |= MS_VERBOSE; + tmpfs_root_mountflags &= ~MS_RDONLY; + err = sys_mount("tmpfs", "/tmp_root", "tmpfs", tmpfs_root_mountflags, + tmpfs_options); + if (err) { + (void)sys_rmdir("/tmp_root"); + printk(KERN_ERR "INITRAMFS: unable to mount tmpfs filesystem (%d), using normal ramfs.\n", err); + return -1; + } + printk ("INITRAMFS: tmpfs mounted.\n"); + if ( (err = sys_chdir("/tmp_root")) < 0) + printk(KERN_ERR "INITRAMFS: unable change to new root (%d).\n", err); + return 0; +} +#endif + +int __init populate_rootfs(int first_invocation) +{ + char *err; + + if (first_invocation) { + err = unpack_to_rootfs(__initramfs_start, + __initramfs_end - __initramfs_start, 0); + if (err) + panic(err); + } #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) { int fd; + +#ifdef CONFIG_INIT_TMPFS + if (first_invocation) { + printk(KERN_INFO "INITRAMFS: delaying decompression of initramfs to make use of tmpfs...\n"); + return 0; + } +#endif + printk(KERN_INFO "checking if image is initramfs..."); err = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start, 1); if (!err) { printk(" it is\n"); +#ifdef CONFIG_INIT_TMPFS + mount_tmpfs_root(); +#endif unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start, 0); free_initrd(); - return; + return 1; } printk("it isn't (%s); looks like an initrd\n", err); fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 700); @@ -527,4 +589,5 @@ } } #endif + return 0; } diff -u linux-2.6.16.29-orig/init/Kconfig linux-2.6.16.29/init/Kconfig --- linux-2.6.16.29-orig/init/Kconfig 2006-09-12 20:02:10.000000000 +0200 +++ linux-2.6.16.29/init/Kconfig 2006-09-23 15:30:16.443035847 +0200 @@ -354,6 +354,15 @@ option replaces shmem and tmpfs with the much simpler ramfs code, which may be appropriate on small systems without swap. +config INIT_TMPFS + bool "Use tmpfs for initial ramfs" if EMBEDDED + default y + depends on TMPFS && BLK_DEV_INITRD + help + Use tmpfs for initial ramdisk. To achieve this the cpio archive for + the initial ram is extracted at the end of the boot process. If you + need the contents of the archive earlier you can't use this. + config CC_ALIGN_FUNCTIONS int "Function alignment" if EMBEDDED default 0 diff -u linux-2.6.16.29-orig/init/main.c linux-2.6.16.29/init/main.c --- linux-2.6.16.29-orig/init/main.c 2006-09-12 20:02:10.000000000 +0200 +++ linux-2.6.16.29/init/main.c 2006-09-23 19:47:46.226994596 +0200 @@ -85,7 +85,7 @@ extern void prio_tree_init(void); extern void radix_tree_init(void); extern void free_initmem(void); -extern void populate_rootfs(void); +extern int populate_rootfs(int); extern void driver_init(void); extern void prepare_namespace(void); #ifdef CONFIG_ACPI @@ -682,7 +682,7 @@ * Do this before initcalls, because some drivers want to access * firmware files. */ - populate_rootfs(); + populate_rootfs(1); do_basic_setup();