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().

free_initmem_on_exec() starts the pipe and calls free_initmem once
run_init_process() succeeds.


---

 /dev/null           |    0 
 25-akpm/init/main.c |   35 ++++++++++++++++++++++++++++++++---
 2 files changed, 32 insertions(+), 3 deletions(-)

diff -puN init/main.c~initramfs-search-for-init init/main.c
--- 25/init/main.c~initramfs-search-for-init	2004-03-20 11:52:16.892461344 -0800
+++ 25-akpm/init/main.c	2004-03-20 11:52:16.895460888 -0800
@@ -580,6 +580,29 @@ static void run_init_process(char *init_
 	execve(init_filename, argv_init, envp_init);
 }
 
+static int free_initmem_on_exec_helper(void *data)
+{
+	int *fd = data;
+	char c;
+
+	sys_close(fd[1]);
+	sys_read(fd[0], &c, 1);
+	free_initmem();
+	return 0;
+}
+
+static void free_initmem_on_exec(void)
+{
+	int fd[2];
+
+	do_pipe(fd);
+	kernel_thread(free_initmem_on_exec_helper, &fd, 0);
+
+	sys_dup2(fd[1], 255);   /* to get it out of the way */
+	sys_close(fd[0]);
+	sys_close(fd[1]);
+	sys_fcntl(255, F_SETFD, 1);
+}
 extern void prepare_namespace(void);
 
 static int init(void * unused)
@@ -604,17 +627,23 @@ static int init(void * unused)
 	sched_init_smp();
 	do_basic_setup();
 
-	prepare_namespace();
-
 	/*
 	 * Ok, we have completed the initial bootup, and
 	 * we're essentially up and running. Get rid of the
 	 * initmem segments and start the user-mode stuff..
 	 */
-	free_initmem();
+	free_initmem_on_exec();
 	unlock_kernel();
 	system_running = 1;
 
+       /*
+        * check if there is an early userspace init, if yes
+        * let it do all the things prepare_namespace() would do.
+        */
+	run_init_process("/init");
+
+	prepare_namespace();
+
 	if (sys_open("/dev/console", O_RDWR, 0) < 0)
 		printk("Warning: unable to open an initial console.\n");
 
diff -puN -L trashcan/olaf/linux-2.6.5-rc2/init/main.c /dev/null /dev/null

_