summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1995-12-14 14:25:03 +0000
committerpeter <peter@FreeBSD.org>1995-12-14 14:25:03 +0000
commit13e9bc1430ceeff368f609e7859b917f6d1ebfcf (patch)
treec447f853fcf4bdb45c3fab03ae44849c86f1b4be /sys/ufs
parent133f0415bf0232367ed6a91f02af7a422929f09d (diff)
downloadFreeBSD-src-13e9bc1430ceeff368f609e7859b917f6d1ebfcf.zip
FreeBSD-src-13e9bc1430ceeff368f609e7859b917f6d1ebfcf.tar.gz
*hack alert*! :-) This adds an option to the MFS_ROOT code so that it
is possible to boot a kernel with an empty in-core MFS image, and have it load the image from floppy directly. This is admittedly a hack and would be better replaced by a self-loading ram-disk.
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/mfs/mfs_vfsops.c95
1 files changed, 94 insertions, 1 deletions
diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c
index 28e8ffe..31318d4 100644
--- a/sys/ufs/mfs/mfs_vfsops.c
+++ b/sys/ufs/mfs/mfs_vfsops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mfs_vfsops.c 8.4 (Berkeley) 4/16/94
- * $Id: mfs_vfsops.c,v 1.16 1995/11/28 03:15:58 peter Exp $
+ * $Id: mfs_vfsops.c,v 1.17 1995/12/03 11:17:15 bde Exp $
*/
#include <sys/param.h>
@@ -62,6 +62,11 @@
#include <ufs/mfs/mfsnode.h>
#include <ufs/mfs/mfs_extern.h>
+#ifdef MFS_AUTOLOAD
+# include <sys/stat.h> /* S_IFCHR */
+# include <i386/i386/cons.h> /* console IO */
+#endif
+
extern int mfs_initminiroot __P((caddr_t base));
caddr_t mfs_rootbase; /* address of mini-root in kernel virtual memory */
@@ -95,6 +100,75 @@ VFS_SET(mfs_vfsops, mfs, MOUNT_MFS, 0);
u_char mfs_root[MFS_ROOT*1024] = "MFS Filesystem goes here";
u_char end_mfs_root[] = "MFS Filesystem had better STOP here";
+#ifdef MFS_AUTOLOAD
+/*
+ * XXX: UGLY UGLY UGLY!!!!!
+ * XXX: This whole MFS_ROOT thing would be loads cleaner if we used
+ * XXX: a "proper" ramdisk with a FFS image.
+ *
+ * This is a crude hack to load a floppy image into the MFS image (above)
+ * in case the boot kernel did not have the root image installed due to
+ * kzip size problems in 4MB. -Peter
+ */
+#define IMAGE_BLOCKING (32 * 1024)
+
+int
+mfs_imageload (dev, addr, size)
+ dev_t dev;
+ caddr_t addr;
+ int size;
+{
+ int error, offset, chunk;
+ int maj = major(dev);
+ int mindev = minor(dev);
+ struct iovec iovec;
+ struct uio uio;
+
+ error = (*cdevsw[maj].d_open)(dev, 0, S_IFCHR , (struct proc *)0);
+ if (error) {
+ printf("mfs_imageload: could not open load device c %d,%d\n", maj, mindev);
+ goto out;
+ }
+
+ offset = 0;
+ while (offset < size) {
+
+ /* pick a size to transfer, preferably a whole cylinder */
+ chunk = min(size - offset, IMAGE_BLOCKING);
+
+ /* do I/O to kernel space. Is there a better way ? */
+ iovec.iov_base = addr + offset;
+ iovec.iov_len = chunk;
+ uio.uio_iov = &iovec;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = offset;
+ uio.uio_resid = chunk;
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_READ;
+ uio.uio_procp = (struct proc *)0;
+
+ /* perform the read request */
+ error = (*cdevsw[maj].d_read)(dev, &uio, 0);
+ if (error) {
+ printf("mfs_imageload: read failed! (error %d)\n", error);
+ break;
+ }
+
+ /* sanity check - check there's no leftover... */
+ if (uio.uio_resid != 0) {
+ printf("mfs_imageload: load failing...\n");
+ break;
+ }
+
+ offset += chunk;
+ }
+
+ /* close the driver */
+out:
+ (void)(*cdevsw[maj].d_close)(dev, 0, S_IFCHR, (struct proc *)0);
+ return (error);
+}
+#endif /* MFS_AUTOLOAD */
#endif /* MFS_ROOT */
/*
@@ -165,6 +239,25 @@ mfs_mount(mp, path, data, ndp, p)
/* Location of MFS/FFS superblock */
fs = (struct fs *)(mfs_root + SBOFF);
+#ifdef MFS_AUTOLOAD
+ /*
+ * check if image was installed during build
+ * if not, attempt to load it now
+ */
+
+ /* check for valid super block */
+ if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
+ fs->fs_bsize < sizeof(struct fs)) {
+
+ dev_t dev = makedev(9, 0); /* boot floppy */
+ printf("MFS image not present in boot kernel!\n");
+ printf("Please replace boot disk with MFS disk...\n");
+ printf("Press any key when done.\n");
+ cngetc();
+ mfs_imageload(dev, mfs_root, end_mfs_root - mfs_root);
+ }
+#endif /* MFS_AUTOLOAD */
+
/* recheck for valid super block */
if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
fs->fs_bsize < sizeof(struct fs)) {
OpenPOWER on IntegriCloud