Wipe out the last remains of arch/mips64/boot, rot in pieces ...
[linux-2.6/linux-mips.git] / init / do_mounts_initrd.c
blob1bf482c1406cef0c49c9b36f2d8bd8eb7071e193
2 #include <linux/kernel.h>
3 #include <linux/fs.h>
4 #include <linux/minix_fs.h>
5 #include <linux/ext2_fs.h>
6 #include <linux/romfs_fs.h>
7 #include <linux/initrd.h>
9 #include "do_mounts.h"
11 unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
12 static int __initdata old_fd, root_fd;
13 static int __initdata mount_initrd = 1;
15 static int __init no_initrd(char *str)
17 mount_initrd = 0;
18 return 1;
21 __setup("noinitrd", no_initrd);
23 static int __init do_linuxrc(void * shell)
25 static char *argv[] = { "linuxrc", NULL, };
26 extern char * envp_init[];
28 close(old_fd);close(root_fd);
29 close(0);close(1);close(2);
30 setsid();
31 (void) open("/dev/console",O_RDWR,0);
32 (void) dup(0);
33 (void) dup(0);
34 return execve(shell, argv, envp_init);
37 static void __init handle_initrd(void)
39 int error;
40 int i, pid;
42 real_root_dev = ROOT_DEV;
43 create_dev("/dev/root.old", Root_RAM0, NULL);
44 /* mount initrd on rootfs' /root */
45 mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
46 sys_mkdir("/old", 0700);
47 root_fd = open("/", 0, 0);
48 old_fd = open("/old", 0, 0);
49 /* move initrd over / and chdir/chroot in initrd root */
50 sys_chdir("/root");
51 sys_mount(".", "/", NULL, MS_MOVE, NULL);
52 sys_chroot(".");
53 mount_devfs_fs ();
55 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
56 if (pid > 0) {
57 while (pid != waitpid(-1, &i, 0))
58 yield();
61 /* move initrd to rootfs' /old */
62 sys_fchdir(old_fd);
63 sys_mount("/", ".", NULL, MS_MOVE, NULL);
64 /* switch root and cwd back to / of rootfs */
65 sys_fchdir(root_fd);
66 sys_chroot(".");
67 close(old_fd);
68 close(root_fd);
69 umount_devfs("/old/dev");
71 if (real_root_dev == Root_RAM0) {
72 sys_chdir("/old");
73 return;
76 ROOT_DEV = real_root_dev;
77 mount_root();
79 printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
80 error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
81 if (!error)
82 printk("okay\n");
83 else {
84 int fd = open("/dev/root.old", O_RDWR, 0);
85 printk("failed\n");
86 printk(KERN_NOTICE "Unmounting old root\n");
87 sys_umount("/old", MNT_DETACH);
88 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
89 if (fd < 0) {
90 error = fd;
91 } else {
92 error = sys_ioctl(fd, BLKFLSBUF, 0);
93 close(fd);
95 printk(!error ? "okay\n" : "failed\n");
99 int __init initrd_load(void)
101 if (!mount_initrd)
102 return 0;
104 create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
105 create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
106 /* Load the initrd data into /dev/ram0. Execute it as initrd unless
107 * /dev/ram0 is supposed to be our actual root device, in
108 * that case the ram disk is just set up here, and gets
109 * mounted in the normal path. */
110 if (rd_load_image("/dev/initrd") && ROOT_DEV != Root_RAM0) {
111 handle_initrd();
112 return 1;
114 return 0;