/* Copyright 2002 Johan Rydberg, jrydberg@rtmk.org. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include "io-vfs.h" #include "io-vnode.h" /* Special mounting point (not visible) for the special file system. We use this to detect aliases for device vnodes. */ struct vfs specfs_mount; /* Translation from device name to major number. */ static char *rd_name_map [] = { "hd", 0 }; static int rd_major_map [] = { 0, 0 }; /* Root vnode of the whole system (ie "/"). We get this by calling VFS_ROOT after mounting the root file system. */ struct vnode *rootvp; /* Pointer to mount structure for the root file system. */ struct vfs *rootvfs; /* The VFS switch. Accessed in `md_attach' when adding file system modules. `nvfs' is the maximum number of entries in switch. */ struct vfssw *vfssw; int nvfs = 8; void mountroot (char *rootname) { int index, err = 0, eq; dev_t rdev; char *strp = 0; init_vnodes (); queue_init (&specfs_mount.vfs_vnl); /* We do not want any railing /dev/ prefix of the device. Remove (step over) it here if we detect any prefix. */ if (! strncmp (rootname, "/dev/", 5)) rootname += 5; for (index = 0, eq = 1; rd_name_map [index] && eq; index++) { strp = rd_name_map [index]; eq = strncmp (rootname, strp, strlen (strp)); } if (eq) goto lose; --index; /* The format of the device name is the following: TYPE (2 chars), UNIT (1 number), PARITION (1 char). */ strp = rootname + strlen (rd_name_map [index]); if (!isdigit (strp[0]) || !isalpha (strp[1])) goto lose; /* Contruct a root device number (major/minor) from the information in the root device name string. */ rdev = makedev (rd_major_map [index], ((strp[0] - '0') * 32) + (strp[1] - 'a' + 1)); rootvfs = (struct vfs *) malloc (sizeof (struct vfs)); assert (rootvfs); /* ??? temporary hack. we'll use something else. */ for (index = 0; index < nvfs; index++) { if (vfssw[index].vsw_name && vfssw[index].vsw_ops->mountroot) { rootvfs->vfs_fstype = index; rootvfs->vfs_dev = rdev; rootvfs->vfs_ops = vfssw[index].vsw_ops; queue_init (&rootvfs->vfs_vnl); trace_printf ("mount root"); err = VFS_MOUNTROOT (rootvfs, rdev); if (err) continue; trace_printf ("get root"); err = VFS_ROOT (rootvfs, &rootvp); if (err) { printf ("root failed %d\n", err); assert (0); } rootvfs->vfs_covered = rootvp; rootvp->v_mounted = rootvfs; printf ("root %s (%s) mounted\n", rootname, vfssw[index].vsw_name); fflush (stdout); return; } } printf ("G-SUS\n"); assert (0); return; lose: printf ("%s is not a valid root device\n", rootname); assert (0); }