summaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 23:59:01 -0800
committerLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 23:59:01 -0800
commitfe0976511d3b5cf2894da54bc451e561bd6b1482 (patch)
tree92bbccc5167568aa5b48d466891fb0dab40ba8bd /init
parent800446073f02f3035bffad7f1ced654ff6b474c9 (diff)
v2.5.0.10 -> v2.5.0.11
- Jeff Garzik: no longer support old cards in tulip driver (see separate driver for old tulip chips) - Pat Mochel: driverfs/device model documentation - Ballabio Dario: update eata driver to new IO locking - Ingo Molnar: raid resync with new bio structures (much more efficient) and mempool_resize() - Jens Axboe: bio queue locking
Diffstat (limited to 'init')
-rw-r--r--init/do_mounts.c781
1 files changed, 559 insertions, 222 deletions
diff --git a/init/do_mounts.c b/init/do_mounts.c
index d34fdd7ae7f8..e6a94292c2b4 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -14,37 +14,44 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
#include <linux/nfs_mount.h>
+#include <linux/minix_fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/romfs_fs.h>
#include <asm/uaccess.h>
-/* syscalls missing from unistd.h */
-
-static inline _syscall2(int,mkdir,char *,name,int,mode);
-static inline _syscall1(int,chdir,char *,name);
-static inline _syscall1(int,chroot,char *,name);
-static inline _syscall1(int,unlink,char *,name);
-static inline _syscall3(int,mknod,char *,name,int,mode,dev_t,dev);
-static inline _syscall5(int,mount,char *,dev,char *,dir,char *,type,
- unsigned long,flags,void *,data);
-static inline _syscall2(int,umount,char *,name,int,flags);
-
-extern void rd_load(void);
-extern void initrd_load(void);
+#define BUILD_CRAMDISK
+
extern int get_filesystem_list(char * buf);
extern void wait_for_keypress(void);
-asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
- unsigned long flags, void * data);
+asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
+ unsigned long flags, void *data);
+asmlinkage long sys_mkdir(char *name, int mode);
+asmlinkage long sys_chdir(char *name);
+asmlinkage long sys_chroot(char *name);
+asmlinkage long sys_unlink(char *name);
+asmlinkage long sys_symlink(char *old, char *new);
+asmlinkage long sys_mknod(char *name, int mode, dev_t dev);
+asmlinkage long sys_umount(char *name, int flags);
+asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
#ifdef CONFIG_BLK_DEV_INITRD
unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
#endif
-int root_mountflags = MS_RDONLY;
-char root_device_name[64];
+#ifdef CONFIG_BLK_DEV_RAM
+extern int rd_doload;
+#else
+static int rd_doload = 0;
+#endif
+int root_mountflags = MS_RDONLY | MS_VERBOSE;
+static char root_device_name[64];
/* this is initialized in init/main.c */
kdev_t ROOT_DEV;
+static int do_devfs = 0;
+
static int __init readonly(char *str)
{
if (*str)
@@ -275,91 +282,20 @@ static void __init get_fs_names(char *page)
}
*s = '\0';
}
-
-static void __init mount_root(void)
+static void __init mount_block_root(char *name, int flags)
{
- void *handle;
- char path[64];
- char *name = "/dev/root";
- char *fs_names, *p;
- int do_devfs = 0;
+ char *fs_names = __getname();
+ char *p;
- root_mountflags |= MS_VERBOSE;
-
- fs_names = __getname();
get_fs_names(fs_names);
-
-#ifdef CONFIG_ROOT_NFS
- if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
- void *data;
- data = nfs_root_data();
- if (data) {
- int err = mount("/dev/root", "/root", "nfs", root_mountflags, data);
- if (!err)
- goto done;
- }
- printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
- ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
- }
-#endif
-
-#ifdef CONFIG_BLK_DEV_FD
- if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
-#ifdef CONFIG_BLK_DEV_RAM
- extern int rd_doload;
- extern void rd_load_secondary(void);
-#endif
- floppy_eject();
-#ifndef CONFIG_BLK_DEV_RAM
- printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n");
-#else
- /* rd_doload is 2 for a dual initrd/ramload setup */
- if(rd_doload==2)
- rd_load_secondary();
- else
-#endif
- {
- printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
- wait_for_keypress();
- }
- }
-#endif
-
- devfs_make_root (root_device_name);
- handle = devfs_find_handle (NULL, ROOT_DEVICE_NAME,
- MAJOR (ROOT_DEV), MINOR (ROOT_DEV),
- DEVFS_SPECIAL_BLK, 1);
- if (handle) {
- int n;
- unsigned major, minor;
-
- devfs_get_maj_min (handle, &major, &minor);
- ROOT_DEV = MKDEV (major, minor);
- if (!ROOT_DEV)
- panic("I have no root and I want to scream");
- n = devfs_generate_path (handle, path + 5, sizeof (path) - 5);
- if (n >= 0) {
- name = path + n;
- devfs_mk_symlink (NULL, "root", DEVFS_FL_DEFAULT,
- name + 5, NULL, NULL);
- memcpy (name, "/dev/", 5);
- do_devfs = 1;
- }
- }
- chdir("/dev");
- unlink("root");
- mknod("root", S_IFBLK|0600, kdev_t_to_nr(ROOT_DEV));
- if (do_devfs)
- mount("devfs", ".", "devfs", 0, NULL);
retry:
for (p = fs_names; *p; p += strlen(p)+1) {
- int err;
- err = sys_mount(name,"/root",p,root_mountflags,root_mount_data);
+ int err = sys_mount(name, "/root", p, flags, root_mount_data);
switch (err) {
case 0:
- goto done;
+ goto out;
case -EACCES:
- root_mountflags |= MS_RDONLY;
+ flags |= MS_RDONLY;
goto retry;
case -EINVAL:
continue;
@@ -375,94 +311,324 @@ retry:
kdevname(ROOT_DEV));
}
panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
-
-done:
+out:
putname(fs_names);
- if (do_devfs)
- umount(".", 0);
+ sys_chdir("/root");
+ ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+ printk("VFS: Mounted root (%s filesystem)%s.\n",
+ current->fs->pwdmnt->mnt_sb->s_type->name,
+ (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
}
+
+#ifdef CONFIG_ROOT_NFS
+static int __init mount_nfs_root(void)
+{
+ void *data = nfs_root_data();
-#ifdef CONFIG_BLK_DEV_INITRD
+ if (data && sys_mount("/dev/root","/root","nfs",root_mountflags,data) == 0)
+ return 1;
+ return 0;
+}
+#endif
-static int __init change_root(kdev_t new_root_dev,const char *put_old)
+static int __init create_dev(char *name, kdev_t dev, char *devfs_name)
+{
+ void *handle;
+ char path[64];
+ int n;
+
+ sys_unlink(name);
+ if (!do_devfs)
+ return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev));
+
+ handle = devfs_find_handle(NULL, dev ? NULL : devfs_name,
+ MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1);
+ if (!handle)
+ return -1;
+ n = devfs_generate_path(handle, path + 5, sizeof (path) - 5);
+ if (n < 0)
+ return -1;
+ return sys_symlink(path + n + 5, name);
+}
+
+#ifdef CONFIG_MAC_FLOPPY
+int swim3_fd_eject(int devnum);
+#endif
+static void __init change_floppy(char *fmt, ...)
{
- struct vfsmount *old_rootmnt;
- struct nameidata devfs_nd;
- char *new_devname = kmalloc(strlen("/dev/root.old")+1, GFP_KERNEL);
- int error = 0;
-
- if (new_devname)
- strcpy(new_devname, "/dev/root.old");
-
- /* .. here is directory mounted over root */
- mount("..", ".", NULL, MS_MOVE, NULL);
- chdir("/old");
-
- read_lock(&current->fs->lock);
- old_rootmnt = mntget(current->fs->pwdmnt);
- read_unlock(&current->fs->lock);
-
- /* First unmount devfs if mounted */
- if (path_init("/old/dev", LOOKUP_FOLLOW|LOOKUP_POSITIVE, &devfs_nd))
- error = path_walk("/old/dev", &devfs_nd);
- if (!error) {
- if (devfs_nd.mnt->mnt_sb->s_magic == DEVFS_SUPER_MAGIC &&
- devfs_nd.dentry == devfs_nd.mnt->mnt_root)
- umount("/old/dev", 0);
- path_release(&devfs_nd);
+ extern void wait_for_keypress(void);
+ char buf[80];
+ va_list args;
+ va_start(args, fmt);
+ vsprintf(buf, fmt, args);
+ va_end(args);
+#ifdef CONFIG_BLK_DEV_FD
+ floppy_eject();
+#endif
+#ifdef CONFIG_MAC_FLOPPY
+ swim3_fd_eject(MINOR(ROOT_DEV));
+#endif
+ printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
+ wait_for_keypress();
+}
+
+#ifdef CONFIG_BLK_DEV_RAM
+
+static int __init crd_load(int in_fd, int out_fd);
+
+/*
+ * This routine tries to find a RAM disk image to load, and returns the
+ * number of blocks to read for a non-compressed image, 0 if the image
+ * is a compressed image, and -1 if an image with the right magic
+ * numbers could not be found.
+ *
+ * We currently check for the following magic numbers:
+ * minix
+ * ext2
+ * romfs
+ * gzip
+ */
+static int __init
+identify_ramdisk_image(int fd, int start_block)
+{
+ const int size = 512;
+ struct minix_super_block *minixsb;
+ struct ext2_super_block *ext2sb;
+ struct romfs_super_block *romfsb;
+ int nblocks = -1;
+ unsigned char *buf;
+
+ buf = kmalloc(size, GFP_KERNEL);
+ if (buf == 0)
+ return -1;
+
+ minixsb = (struct minix_super_block *) buf;
+ ext2sb = (struct ext2_super_block *) buf;
+ romfsb = (struct romfs_super_block *) buf;
+ memset(buf, 0xe5, size);
+
+ /*
+ * Read block 0 to test for gzipped kernel
+ */
+ lseek(fd, start_block * BLOCK_SIZE, 0);
+ read(fd, buf, size);
+
+ /*
+ * If it matches the gzip magic numbers, return -1
+ */
+ if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
+ printk(KERN_NOTICE
+ "RAMDISK: Compressed image found at block %d\n",
+ start_block);
+ nblocks = 0;
+ goto done;
}
- ROOT_DEV = new_root_dev;
- mount_root();
+ /* romfs is at block zero too */
+ if (romfsb->word0 == ROMSB_WORD0 &&
+ romfsb->word1 == ROMSB_WORD1) {
+ printk(KERN_NOTICE
+ "RAMDISK: romfs filesystem found at block %d\n",
+ start_block);
+ nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
+ goto done;
+ }
- chdir("/root");
- ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
- printk("VFS: Mounted root (%s filesystem)%s.\n",
- current->fs->pwdmnt->mnt_sb->s_type->name,
- (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
+ /*
+ * Read block 1 to test for minix and ext2 superblock
+ */
+ lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
+ read(fd, buf, size);
+
+ /* Try minix */
+ if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
+ minixsb->s_magic == MINIX_SUPER_MAGIC2) {
+ printk(KERN_NOTICE
+ "RAMDISK: Minix filesystem found at block %d\n",
+ start_block);
+ nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
+ goto done;
+ }
+
+ /* Try ext2 */
+ if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
+ printk(KERN_NOTICE
+ "RAMDISK: ext2 filesystem found at block %d\n",
+ start_block);
+ nblocks = le32_to_cpu(ext2sb->s_blocks_count);
+ goto done;
+ }
-#if 1
- shrink_dcache();
- printk("change_root: old root has d_count=%d\n",
- atomic_read(&old_rootmnt->mnt_root->d_count));
+ printk(KERN_NOTICE
+ "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
+ start_block);
+
+done:
+ lseek(fd, start_block * BLOCK_SIZE, 0);
+ kfree(buf);
+ return nblocks;
+}
#endif
- error = mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
- if (error) {
- int blivet;
- struct block_device *ramdisk = old_rootmnt->mnt_sb->s_bdev;
-
- atomic_inc(&ramdisk->bd_count);
- blivet = blkdev_get(ramdisk, FMODE_READ, 0, BDEV_FS);
- printk(KERN_NOTICE "Trying to unmount old root ... ");
- umount("/old", MNT_DETACH);
- if (!blivet) {
- blivet = ioctl_by_bdev(ramdisk, BLKFLSBUF, 0);
- blkdev_put(ramdisk, BDEV_FS);
- }
- if (blivet) {
- printk(KERN_ERR "error %d\n", blivet);
- } else {
- printk("okay\n");
- error = 0;
+static int __init rd_load_image(char *from)
+{
+ int res = 0;
+
+#ifdef CONFIG_BLK_DEV_RAM
+ int in_fd, out_fd;
+ int nblocks, rd_blocks, devblocks, i;
+ char *buf;
+ unsigned short rotate = 0;
+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+ char rotator[4] = { '|' , '/' , '-' , '\\' };
+#endif
+
+ out_fd = open("/dev/ram", O_RDWR, 0);
+ if (out_fd < 0)
+ goto out;
+
+ in_fd = open(from, O_RDONLY, 0);
+ if (in_fd < 0)
+ goto noclose_input;
+
+ nblocks = identify_ramdisk_image(in_fd, rd_image_start);
+ if (nblocks < 0)
+ goto done;
+
+ if (nblocks == 0) {
+#ifdef BUILD_CRAMDISK
+ if (crd_load(in_fd, out_fd) == 0)
+ goto successful_load;
+#else
+ printk(KERN_NOTICE
+ "RAMDISK: Kernel does not support compressed "
+ "RAM disk images\n");
+#endif
+ goto done;
+ }
+
+ /*
+ * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
+ * rd_load_image will work only with filesystem BLOCK_SIZE wide!
+ * So make sure to use 1k blocksize while generating ext2fs
+ * ramdisk-images.
+ */
+ if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
+ rd_blocks = 0;
+ else
+ rd_blocks >>= 1;
+
+ if (nblocks > rd_blocks) {
+ printk("RAMDISK: image too big! (%d/%d blocks)\n",
+ nblocks, rd_blocks);
+ goto done;
+ }
+
+ /*
+ * OK, time to copy in the data
+ */
+ buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
+ if (buf == 0) {
+ printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
+ goto done;
+ }
+
+ if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
+ devblocks = 0;
+ else
+ devblocks >>= 1;
+
+ if (strcmp(from, "/dev/initrd") == 0)
+ devblocks = nblocks;
+
+ if (devblocks == 0) {
+ printk(KERN_ERR "RAMDISK: could not determine device size\n");
+ goto done;
+ }
+
+ printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ",
+ nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
+ for (i=0; i < nblocks; i++) {
+ if (i && (i % devblocks == 0)) {
+ printk("done disk #%d.\n", i/devblocks);
+ rotate = 0;
+ if (close(in_fd)) {
+ printk("Error closing the disk.\n");
+ goto noclose_input;
+ }
+ change_floppy("disk #%d", i/devblocks+1);
+ in_fd = open(from, O_RDONLY, 0);
+ if (in_fd < 0) {
+ printk("Error opening disk.\n");
+ goto noclose_input;
+ }
+ printk("Loading disk #%d... ", i/devblocks+1);
}
- } else {
- spin_lock(&dcache_lock);
- if (new_devname) {
- void *p = old_rootmnt->mnt_devname;
- old_rootmnt->mnt_devname = new_devname;
- new_devname = p;
+ read(in_fd, buf, BLOCK_SIZE);
+ write(out_fd, buf, BLOCK_SIZE);
+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+ if (!(i % 16)) {
+ printk("%c\b", rotator[rotate & 0x3]);
+ rotate++;
}
- spin_unlock(&dcache_lock);
+#endif
}
+ printk("done.\n");
+ kfree(buf);
- /* put the old stuff */
- mntput(old_rootmnt);
- kfree(new_devname);
- return error;
+successful_load:
+ res = 1;
+done:
+ close(in_fd);
+noclose_input:
+ close(out_fd);
+out:
+ sys_unlink("/dev/ram");
+#endif
+ return res;
+}
+
+static int __init rd_load_disk(int n)
+{
+#ifdef CONFIG_BLK_DEV_RAM
+ extern int rd_prompt;
+ if (rd_prompt)
+ change_floppy("root floppy disk to be loaded into RAM disk");
+ create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
+#endif
+ return rd_load_image("/dev/root");
}
+static void __init mount_root(void)
+{
+#ifdef CONFIG_ROOT_NFS
+ if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
+ if (mount_nfs_root()) {
+ sys_chdir("/root");
+ ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+ printk("VFS: Mounted root (nfs filesystem).\n");
+ return;
+ }
+ printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
+ ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
+ }
#endif
+ devfs_make_root(root_device_name);
+ create_dev("/dev/root", ROOT_DEV, root_device_name);
+#ifdef CONFIG_BLK_DEV_FD
+ if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
+ /* rd_doload is 2 for a dual initrd/ramload setup */
+ if (rd_doload==2) {
+ if (rd_load_disk(1)) {
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 1);
+ create_dev("/dev/root", ROOT_DEV, NULL);
+ }
+ } else
+ change_floppy("root floppy");
+ }
+#endif
+ mount_block_root("/dev/root", root_mountflags);
+}
#ifdef CONFIG_BLK_DEV_INITRD
static int do_linuxrc(void * shell)
@@ -470,9 +636,9 @@ static int do_linuxrc(void * shell)
static char *argv[] = { "linuxrc", NULL, };
extern char * envp_init[];
- chdir("/root");
- mount(".", "/", NULL, MS_MOVE, NULL);
- chroot(".");
+ sys_chdir("/root");
+ sys_mount(".", "/", NULL, MS_MOVE, NULL);
+ sys_chroot(".");
mount_devfs_fs ();
@@ -486,76 +652,247 @@ static int do_linuxrc(void * shell)
#endif
+static void __init handle_initrd(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ int ram0 = kdev_t_to_nr(MKDEV(RAMDISK_MAJOR,0));
+ int error;
+ int i, pid;
+
+ create_dev("/dev/root.old", ram0, NULL);
+ mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
+ sys_mkdir("/old", 0700);
+ sys_chdir("/old");
+
+ pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
+ if (pid > 0) {
+ while (pid != wait(&i)) {
+ current->policy |= SCHED_YIELD;
+ schedule();
+ }
+ }
+
+ sys_mount("..", ".", NULL, MS_MOVE, NULL);
+ sys_umount("/old/dev", 0);
+
+ if (real_root_dev == ram0) {
+ sys_chdir("/old");
+ return;
+ }
+
+ ROOT_DEV = real_root_dev;
+ mount_root();
+
+ printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
+ error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
+ if (!error)
+ printk("okay\n");
+ else {
+ int fd = open("/dev/root.old", O_RDWR, 0);
+ printk("failed\n");
+ printk(KERN_NOTICE "Unmounting old root\n");
+ sys_umount("/old", MNT_DETACH);
+ printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
+ if (fd < 0) {
+ error = fd;
+ } else {
+ error = sys_ioctl(fd, BLKFLSBUF, 0);
+ close(fd);
+ }
+ printk(error ? "okay\n" : "failed\n");
+ }
+#endif
+}
+
+static int __init initrd_load(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+ create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
+ create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
+#endif
+ return rd_load_image("/dev/initrd");
+}
+
/*
* Prepare the namespace - decide what/where to mount, load ramdisks, etc.
*/
void prepare_namespace(void)
{
+ int do_initrd = 0;
+ int is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
#ifdef CONFIG_BLK_DEV_INITRD
- int real_root_mountflags = root_mountflags;
if (!initrd_start)
mount_initrd = 0;
if (mount_initrd)
- root_mountflags &= ~MS_RDONLY;
+ do_initrd = 1;
real_root_dev = ROOT_DEV;
#endif
- mkdir("/dev", 0700);
- mkdir("/root", 0700);
-
-#ifdef CONFIG_BLK_DEV_RAM
-#ifdef CONFIG_BLK_DEV_INITRD
- if (mount_initrd)
- initrd_load();
- else
-#endif
- rd_load();
+ sys_mkdir("/dev", 0700);
+ sys_mkdir("/root", 0700);
+#ifdef CONFIG_DEVFS_FS
+ sys_mount("devfs", "/dev", "devfs", 0, NULL);
+ do_devfs = 1;
#endif
- /* Mount the root filesystem.. */
+ create_dev("/dev/root", ROOT_DEV, NULL);
+ if (do_initrd) {
+ if (initrd_load() && ROOT_DEV != MKDEV(RAMDISK_MAJOR, 0)) {
+ handle_initrd();
+ goto out;
+ }
+ } else if (is_floppy && rd_doload && rd_load_disk(0))
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
mount_root();
- chdir("/root");
- ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
- printk("VFS: Mounted root (%s filesystem)%s.\n",
- current->fs->pwdmnt->mnt_sb->s_type->name,
- (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
+out:
+ sys_umount("/dev", 0);
+ sys_mount(".", "/", NULL, MS_MOVE, NULL);
+ sys_chroot(".");
+ mount_devfs_fs ();
+}
-#ifdef CONFIG_BLK_DEV_INITRD
- root_mountflags = real_root_mountflags;
- if (mount_initrd && ROOT_DEV != real_root_dev
- && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
- int error;
- int i, pid;
- mkdir("/old", 0700);
- chdir("/old");
-
- pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
- if (pid > 0) {
- while (pid != wait(&i)) {
- current->policy |= SCHED_YIELD;
- schedule();
- }
- }
- if (MAJOR(real_root_dev) != RAMDISK_MAJOR
- || MINOR(real_root_dev) != 0) {
- error = change_root(real_root_dev,"/initrd");
- if (error)
- printk(KERN_ERR "Change root to /initrd: "
- "error %d\n",error);
-
- chdir("/root");
- mount(".", "/", NULL, MS_MOVE, NULL);
- chroot(".");
-
- mount_devfs_fs ();
- return;
- }
- chroot("..");
- chdir("/");
- return;
- }
+#ifdef BUILD_CRAMDISK
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args) args
+
+#ifndef memzero
+#define memzero(s, n) memset ((s), 0, (n))
#endif
- mount(".", "/", NULL, MS_MOVE, NULL);
- chroot(".");
- mount_devfs_fs ();
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define INBUFSIZ 4096
+#define WSIZE 0x8000 /* window size--must be a power of two, and */
+ /* at least 32K for zip's deflate method */
+
+static uch *inbuf;
+static uch *window;
+
+static unsigned insize; /* valid bytes in inbuf */
+static unsigned inptr; /* index of next byte to be processed in inbuf */
+static unsigned outcnt; /* bytes in output buffer */
+static int exit_code;
+static long bytes_out;
+static int crd_infd, crd_outfd;
+
+#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions (stubbed out) */
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+#define STATIC static
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+#include "../lib/inflate.c"
+
+static void __init *malloc(int size)
+{
+ return kmalloc(size, GFP_KERNEL);
+}
+
+static void __init free(void *where)
+{
+ kfree(where);
+}
+
+static void __init gzip_mark(void **ptr)
+{
}
+
+static void __init gzip_release(void **ptr)
+{
+}
+
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int __init fill_inbuf(void)
+{
+ if (exit_code) return -1;
+
+ insize = read(crd_infd, inbuf, INBUFSIZ);
+ if (insize == 0) return -1;
+
+ inptr = 1;
+
+ return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void __init flush_window(void)
+{
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, ch;
+
+ write(crd_outfd, window, outcnt);
+ in = window;
+ for (n = 0; n < outcnt; n++) {
+ ch = *in++;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ outcnt = 0;
+}
+
+static void __init error(char *x)
+{
+ printk(KERN_ERR "%s", x);
+ exit_code = 1;
+}
+
+static int __init crd_load(int in_fd, int out_fd)
+{
+ int result;
+
+ insize = 0; /* valid bytes in inbuf */
+ inptr = 0; /* index of next byte to be processed in inbuf */
+ outcnt = 0; /* bytes in output buffer */
+ exit_code = 0;
+ bytes_out = 0;
+ crc = (ulg)0xffffffffL; /* shift register contents */
+
+ crd_infd = in_fd;
+ crd_outfd = out_fd;
+ inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
+ if (inbuf == 0) {
+ printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
+ return -1;
+ }
+ window = kmalloc(WSIZE, GFP_KERNEL);
+ if (window == 0) {
+ printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
+ kfree(inbuf);
+ return -1;
+ }
+ makecrc();
+ result = gunzip();
+ kfree(inbuf);
+ kfree(window);
+ return result;
+}
+
+#endif /* BUILD_CRAMDISK */