From: Olaf Hering <olh@suse.de>

initramfs can not be used in current 2.6 kernels, the files will never be
executed because prepare_namespace doesn't care about them.  The only way to
workaround that limitation is a root=0:0 cmdline option to force rootfs as
root filesystem.  This will break further booting because rootfs is not the
final root filesystem.

This patch checks for the presence of /init which comes from the cpio archive
(and thats the only way to store files into the rootfs).  This binary/script
has to do all the work of prepare_namespace().


---

 25-akpm/Documentation/early-userspace/README |   26 ++++++++++++++++++++++++++
 25-akpm/init/main.c                          |    7 +++++++
 2 files changed, 33 insertions(+)

diff -puN Documentation/early-userspace/README~initramfs-search-for-init-orig Documentation/early-userspace/README
--- 25/Documentation/early-userspace/README~initramfs-search-for-init-orig	2004-03-22 00:38:02.064936960 -0800
+++ 25-akpm/Documentation/early-userspace/README	2004-03-22 00:38:02.067936504 -0800
@@ -71,5 +71,31 @@ custom initramfs images that meet your n
 For questions and help, you can sign up for the early userspace
 mailing list at http://www.zytor.com/mailman/listinfo/klibc
 
+How does it work?
+=================
+
+The kernel has currently 3 ways to mount the root filesystem:
+
+a) all required device and filesystem drivers compiled into the kernel, no
+   initrd.  init/main.c:init() will call prepare_namespace() to mount the
+   final root filesystem, based on the root= option and optional init= to run
+   some other init binary than listed at the end of init/main.c:init().
+
+b) some device and filesystem drivers built as modules and stored in an
+   initrd.  The initrd must contain a binary '/linuxrc' which is supposed to
+   load these driver modules.  It is also possible to mount the final root
+   filesystem via linuxrc and use the pivot_root syscall.  The initrd is
+   mounted and executed via prepare_namespace().
+
+c) using initramfs.  The call to prepare_namespace() must be skipped.
+   This means that a binary must do all the work.  Said binary can be stored
+   into initramfs either via modifying usr/gen_init_cpio.c or via the new
+   initrd format, an cpio archive.  It must be called "/init".  This binary
+   is responsible to do all the things prepare_namespace() would do.
+
+   To remain backwards compatibility, the /init binary will only run if it
+   comes via an initramfs cpio archive.  If this is not the case,
+   init/main.c:init() will run prepare_namespace() to mount the final root
+   and exec one of the predefined init binaries.
 
 Bryan O'Sullivan <bos@serpentine.com>
diff -puN init/main.c~initramfs-search-for-init-orig init/main.c
--- 25/init/main.c~initramfs-search-for-init-orig	2004-03-22 00:38:02.065936808 -0800
+++ 25-akpm/init/main.c	2004-03-22 00:38:02.068936352 -0800
@@ -604,6 +604,13 @@ static int init(void * unused)
 	smp_init();
 	do_basic_setup();
 
+       /*
+        * check if there is an early userspace init, if yes
+        * let it do all the work
+        */
+       if (sys_access("/init", 0) == 0)
+               execute_command = "/init";
+       else
 	prepare_namespace();
 
 	/*

_