diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 3e0878e..9b261ec 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -16,13 +16,13 @@
 #include <linux/initrd.h>
 #include <linux/sched.h>
 #include <linux/freezer.h>
-#include <linux/kmod.h>
 
 #include "do_mounts.h"
 
 unsigned long initrd_start, initrd_end;
 int initrd_below_start_ok;
 unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
+static int __initdata old_fd, root_fd;
 static int __initdata mount_initrd = 1;
 
 static int __init no_initrd(char *str)
@@ -33,37 +33,33 @@ static int __init no_initrd(char *str)
 
 __setup("noinitrd", no_initrd);
 
-static int init_linuxrc(struct subprocess_info *info, struct cred *new)
+static int __init do_linuxrc(void *_shell)
 {
-	sys_unshare(CLONE_FS | CLONE_FILES);
-	/* stdin/stdout/stderr for /linuxrc */
-	sys_open("/dev/console", O_RDWR, 0);
-	sys_dup(0);
-	sys_dup(0);
-	/* move initrd over / and chdir/chroot in initrd root */
-	sys_chdir("/root");
-	sys_mount(".", "/", NULL, MS_MOVE, NULL);
-	sys_chroot(".");
+	static const char *argv[] = { "linuxrc", NULL, };
+	extern const char *envp_init[];
+	const char *shell = _shell;
+
+	sys_close(old_fd);sys_close(root_fd);
 	sys_setsid();
-	return 0;
+	return sys_execve(shell, argv, envp_init);
 }
 
 static void __init handle_initrd(void)
 {
-	struct subprocess_info *info;
-	static char *argv[] = { "linuxrc", NULL, };
-	extern char *envp_init[];
 	int error;
+	int pid;
 
 	real_root_dev = new_encode_dev(ROOT_DEV);
 	create_dev("/dev/root.old", Root_RAM0);
 	/* mount initrd on rootfs' /root */
 	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
 	sys_mkdir("/old", 0700);
-	sys_chdir("/old");
-
-	/* try loading default modules from initrd */
-	load_default_modules();
+	root_fd = sys_open("/", 0, 0);
+	old_fd = sys_open("/old", 0, 0);
+	/* move initrd over / and chdir/chroot in initrd root */
+	sys_chdir("/root");
+	sys_mount(".", "/", NULL, MS_MOVE, NULL);
+	sys_chroot(".");
 
 	/*
 	 * In case that a resume from disk is carried out by linuxrc or one of
@@ -71,25 +67,27 @@ static void __init handle_initrd(void)
 	 */
 	current->flags |= PF_FREEZER_SKIP;
 
-	info = call_usermodehelper_setup("/linuxrc", argv, envp_init,
-					 GFP_KERNEL, init_linuxrc, NULL, NULL);
-	if (!info)
-		return;
-	call_usermodehelper_exec(info, UMH_WAIT_PROC);
+	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
+	if (pid > 0)
+		while (pid != sys_wait4(-1, NULL, 0, NULL))
+			yield();
 
 	current->flags &= ~PF_FREEZER_SKIP;
 
 	/* move initrd to rootfs' /old */
-	sys_mount("..", ".", NULL, MS_MOVE, NULL);
+	sys_fchdir(old_fd);
+	sys_mount("/", ".", NULL, MS_MOVE, NULL);
 	/* switch root and cwd back to / of rootfs */
-	sys_chroot("..");
+	sys_fchdir(root_fd);
+	sys_chroot(".");
+	sys_close(old_fd);
+	sys_close(root_fd);
 
 	if (new_decode_dev(real_root_dev) == Root_RAM0) {
 		sys_chdir("/old");
 		return;
 	}
 
-	sys_chdir("/");
 	ROOT_DEV = new_decode_dev(real_root_dev);
 	mount_root();
 
