]> Zhao Yanbai Git Server - minix.git/commitdiff
Initial root filesystem is now on a ramdisk that is part of the image.
authorPhilip Homburg <philip@cs.vu.nl>
Wed, 15 Feb 2006 11:18:21 +0000 (11:18 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Wed, 15 Feb 2006 11:18:21 +0000 (11:18 +0000)
26 files changed:
commands/scripts/binsizes.sh
commands/simple/Makefile
commands/simple/cdprobe.c [new file with mode: 0644]
commands/simple/loadramdisk.c [new file with mode: 0644]
commands/simple/mkfs.c
commands/simple/newroot.c [new file with mode: 0644]
drivers/bios_wini/Makefile
drivers/memory/Makefile
drivers/memory/imgrd.c [new file with mode: 0644]
drivers/memory/local.h [new file with mode: 0644]
drivers/memory/memory.c
drivers/memory/ramdisk/Makefile [new file with mode: 0644]
drivers/memory/ramdisk/bintoc.c [new file with mode: 0644]
drivers/memory/ramdisk/mtab [new file with mode: 0755]
drivers/memory/ramdisk/proto [new file with mode: 0644]
drivers/memory/ramdisk/rc [new file with mode: 0644]
etc/binary_sizes.big
etc/rc
include/minix/com.h
include/minix/dmap.h
kernel/table.c
servers/fs/dmap.c
servers/fs/main.c
servers/fs/mount.c
servers/fs/path.c
tools/Makefile

index bc6716ddc23e6eaf3cdf6aed5d12f2fab1fc61b1..36ffcd5b147b078f39de07c6fd72cdba48aef050 100644 (file)
@@ -17,3 +17,4 @@ then  cat "$t" | while read line
        do      awk '{ print "chmem =" $2 " " $1 " >/dev/null 2>&1 "}'
        done | /bin/sh
 fi
+exit 0
index d58d2b0455b870ce819f7f98702f0d822befc4c9..6d7afcec53b97116d735987c5c6e92ce26254e03 100755 (executable)
@@ -51,6 +51,7 @@ ALL   = \
        calendar \
        cat \
        cdiff \
+       cdprobe \
        cgrep \
        chmem \
        chmod \
@@ -110,6 +111,7 @@ ALL = \
        last \
        leave \
        life \
+       loadramdisk \
        login \
        look \
        lp \
@@ -128,6 +130,7 @@ ALL = \
        mount \
        mt \
        nm \
+       newroot \
        nonamed \
        nice \
        od \
@@ -255,6 +258,10 @@ cdiff:     cdiff.c
        $(CCLD) -o $@ $?
        @install -S 28kw $@
 
+cdprobe: cdprobe.c
+       $(CCLD) -o $@ $?
+       @install -S 28kw $@
+
 cgrep: cgrep.c
        $(CCLD) -o $@ $?
        @install -S 5kw $@
@@ -491,6 +498,10 @@ life:      life.c
        $(CCLD) -o $@ $? -lcurses
        @install -S 15kw $@
 
+loadramdisk:   loadramdisk.c
+       $(CCLD) -o $@ $?
+       install -S 4kw $@
+
 login: login.c
        $(CCLD) -o $@ $?
        install -S 4kw $@
@@ -559,6 +570,10 @@ mt:        mt.c
        $(CCLD) -o $@ $?
        @install -S 4kw $@
 
+newroot:       newroot.c
+       $(CCLD) -o $@ $?
+       @install -S 32kw $@
+
 nm:    nm.c
        $(CCLD) -o $@ $?
        @install -S 32kw $@
@@ -892,6 +907,7 @@ install:    \
        /usr/bin/calendar \
        /usr/bin/cat \
        /usr/bin/cdiff \
+       /usr/bin/cdprobe \
        /usr/bin/cgrep \
        /usr/bin/chmem \
        /usr/bin/chmod \
@@ -970,6 +986,7 @@ install:    \
                /usr/bin/uptime \
        /usr/bin/leave \
        /usr/bin/life \
+       /usr/bin/loadramdisk \
        /usr/bin/login \
        /usr/bin/look \
        /usr/bin/lp \
@@ -987,6 +1004,7 @@ install:   \
        /usr/bin/modem \
        /usr/bin/mount \
        /usr/bin/mt \
+       /usr/bin/newroot \
        /usr/bin/nm \
        /usr/bin/nice \
        /usr/bin/nonamed \
@@ -1126,6 +1144,9 @@ install:  \
 /usr/bin/cdiff:        cdiff
        install -cs -o bin $? $@
 
+/usr/bin/cdprobe: cdprobe
+       install -cs -o bin $? $@
+
 /usr/bin/cgrep:        cgrep
        install -cs -o bin $? $@
 
@@ -1334,6 +1355,9 @@ install:  \
 /usr/bin/life: life
        install -cs -o bin $? $@
 
+/usr/bin/loadramdisk:  loadramdisk
+       install -cs -o bin $? $@
+
 /usr/bin/login:        login
        install -cs -o bin $? $@
 
@@ -1385,6 +1409,9 @@ install:  \
 /usr/bin/mt:   mt
        install -cs -o bin $? $@
 
+/usr/bin/newroot:      newroot
+       install -cs -o bin $? $@
+
 /usr/bin/nm:   nm
        install -cs -o bin $? $@
 
diff --git a/commands/simple/cdprobe.c b/commands/simple/cdprobe.c
new file mode 100644 (file)
index 0000000..7956269
--- /dev/null
@@ -0,0 +1,130 @@
+/* This file contains some code to guess where we have to load the
+ * RAM image device from, if started from CD. (In this case it's hard
+ * to tell where this is without diving into BIOS heuristics.)
+ *
+ * There is some nasty hard-codery in here ( MINIX cd label) that can be
+ * improved on.
+ *
+ * Changes:
+ *   Jul 14, 2005   Created (Ben Gras)
+ *   Feb 10, 2006   Changed into a standalone program (Philip Homburg)
+ */
+
+#define CD_SECTOR      2048
+#define SUPER_OFF      1024
+#define AT_MINORS      4
+#define MAGIC_OFF      24
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../../servers/fs/const.h"
+
+char pvd[CD_SECTOR];
+
+/*===========================================================================*
+ *                             cdprobe                                      *
+ *===========================================================================*/
+int main(void)
+{
+       int i, r, fd, minor, found;
+       off_t pos;
+       u16_t *magicp;
+       char name1[]= "/dev/c0dX";
+       char name2[]= "/dev/c0dXpY";
+
+       found= 0;
+       for(i = 0; i < AT_MINORS; i++) {
+               name1[8]= '0' + i;
+
+               fd = open(name1, O_RDONLY);
+               if (fd < 0)
+               {
+                       if (errno != ENXIO)
+                       {
+                               fprintf(stderr, "open '%s' failed: %s\n",
+                                       name1, strerror(errno));
+                       }
+                       continue;
+               }
+
+               pos= lseek(fd, 16*CD_SECTOR, SEEK_SET);
+               if (pos != 16*CD_SECTOR)
+               {
+                       /* Strange, do we need to issue a warning? */
+                       close(fd);
+                       continue;
+               }
+               r = read(fd, pvd, sizeof(pvd));
+               if (r != sizeof(pvd))
+               {
+                       fprintf(stderr,
+                               "error reading CD label from '%s': %s\n",
+                               name1, strerror(errno));
+                       close(fd);
+                       continue;
+               }
+               close(fd);
+
+               /* Check PVD ID. */
+               if (pvd[0] !=  1  || pvd[1] != 'C' || pvd[2] != 'D' ||
+                  pvd[3] != '0' || pvd[4] != '0' || pvd[5] != '1' ||
+                  pvd[6] != 1 ||
+                  strncmp(pvd + 40, "MINIX", 5) != 0) {
+                       continue;
+               }
+
+               /* 3. Both c0dXp1 and p2 should have a superblock. */
+               found= 1;       /* Assume everything is okay */
+               for (minor = 1; minor <= 2; minor++) {
+                       name2[8]= '0' + i;
+                       name2[10]= '0' + minor;
+
+                       fd = open(name2, O_RDONLY);
+                       if (fd < 0)
+                       {
+                               if (errno != ENXIO)
+                               {
+                                       fprintf(stderr,
+                                               "open '%s' failed: %s\n",
+                                               name2, strerror(errno));
+                               }
+                               found= 0;
+                               break;
+                       }
+                       r = read(fd, pvd, sizeof(pvd));
+                       if (r != sizeof(pvd))
+                       {
+                               fprintf(stderr,
+                               "error reading super block from '%s': %s\n",
+                                       name2, strerror(errno));
+                               close(fd);
+                               found= 0;
+                               break;
+                       }
+                       close(fd);
+
+                       magicp= (u16_t *)&pvd[SUPER_OFF+MAGIC_OFF];
+                       if (*magicp != SUPER_V3)
+                       {
+                               fprintf(stderr, "bad super block on %s\n",
+                                       name2);
+                               found= 0;
+                               break;
+                       }
+               }
+
+               if (found)
+               {
+                       printf("%s\n", name1);
+                       exit(0);
+               }
+       }
+
+       return 1;
+}
+
diff --git a/commands/simple/loadramdisk.c b/commands/simple/loadramdisk.c
new file mode 100644 (file)
index 0000000..60fcfec
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+loadramdisk.c
+
+Copy a device or file specified as argument to /dev/ram
+*/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#define RAM    "/dev/ram"
+
+char buf[10240];
+
+static unsigned long size_device(int fd);
+
+int main(int argc, char *argv[])
+{
+       unsigned long off, size;
+       int r, s, fd, ramfd;
+       char *src;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "Usage: loadramdisk <file>\n");
+               exit(1);
+       }
+       src= argv[1];
+       fd= open(src, O_RDONLY);
+       if (fd < 0)
+       {
+               fprintf(stderr, "Unable to open '%s': %s\n",
+                       src, strerror(errno));
+               exit(1);
+       }
+
+       /* Get the size of the device */
+       errno= 0;
+       size= size_device(fd);
+       if (errno != 0)
+       {
+               fprintf(stderr, "Lseek(end) failed on '%s': %s\n",
+                       src, strerror(errno));
+               exit(1);
+       }
+       if (lseek(fd, 0, SEEK_SET) != 0)
+       {
+               fprintf(stderr, "Lseek(0) failed on '%s': %s\n",
+                       src, strerror(errno));
+               exit(1);
+       }
+
+       ramfd= open(RAM, O_RDWR);
+       if (ramfd < 0)
+       {
+               fprintf(stderr, "Unable to open '%s': %s\n",
+                       RAM, strerror(errno));
+               exit(1);
+       }
+       r= ioctl(ramfd, MIOCRAMSIZE, &size);
+       if (r != 0)
+       {
+               fprintf(stderr, "MIOCRAMSIZE %lu failed on '%s': %s\n",
+                       size, RAM, strerror(errno));
+               exit(1);
+       }
+
+       off= 0;
+       while (off < size)
+       {
+               r= read(fd, buf, sizeof(buf));
+               if (r <= 0)
+               {
+                       fprintf(stderr, "error reading '%s': %s\n",
+                               src, r == 0 ? "unexpected EOF" :
+                               strerror(errno));
+                       exit(1);
+               }
+               s= write(ramfd, buf, r);
+               if (s != r)
+               {
+                       fprintf(stderr, "error writing to '%s': %s\n",
+                               s >= 0 ? "short write" : strerror(errno));
+                       exit(1);
+               }
+               off += r;
+       }
+       exit(0);
+}
+
+static unsigned long size_device(int fd)
+{
+       char b;
+       int r;
+       unsigned long low, mid, high;
+
+       /* Try to find the size of a device using binary search */
+       low= 0;
+       high= -1;
+
+       while (mid= low+(high-low)/2, mid > low)
+       {
+               if (lseek(fd, mid, SEEK_SET) != mid)
+               {
+                       fprintf(stderr, "lseek to %lu failed: %s\n",
+                               mid, strerror(errno));
+                       exit(1);
+               }
+               r= read(fd, &b, 1);
+               if (r < 0)
+               {
+                       fprintf(stderr, "read failed at position %lu: %s\n",
+                               mid, strerror(errno));
+                       exit(1);
+               }
+               if (r > 0)
+                       low= mid;
+               else
+                       high= mid;
+       }
+       return high;
+}
index 9613e87d18c4e5d9d9eb4066f86ec4c3064a1886..3f0d4d30713507df26e55bc584bae333af45e5fd 100755 (executable)
@@ -423,7 +423,8 @@ char *device;
   struct stat st;
 
   if ((fd = open(device, O_RDONLY)) == -1) {
-       perror("sizeup open");
+       if (errno != ENOENT)
+               perror("sizeup open");
        return 0;
   }
   if (ioctl(fd, DIOCGETP, &entry) == -1) {
@@ -1062,9 +1063,25 @@ char *devname;                   /* /dev/hd1 or whatever */
 {
 /* Check to see if the special file named in s is mounted. */
 
-  int n;
+  int n, r;
+  struct stat sb;
   char special[PATH_MAX + 1], mounted_on[PATH_MAX + 1], version[10], rw_flag[10];
 
+  r= stat(devname, &sb);
+  if (r == -1)
+  {
+       if (errno == ENOENT)
+               return; /* Does not exist, and therefore not mounted. */
+       fprintf(stderr, "%s: stat %s failed: %s\n",
+               progname, devname, strerror(errno));
+       exit(1);
+  }
+  if (!S_ISBLK(sb.st_mode))
+  {
+       /* Not a block device and therefore not mounted. */
+       return;
+  }
+
   if (load_mtab("mkfs") < 0) return;
   while (1) {
        n = get_mtab_entry(special, mounted_on, version, rw_flag);
diff --git a/commands/simple/newroot.c b/commands/simple/newroot.c
new file mode 100644 (file)
index 0000000..4a9a047
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+newroot.c
+
+Replace the current root with a new one
+*/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+       int r;
+       char *dev;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "Usage: newroot <block-special>\n");
+               exit(1);
+       }
+       dev= argv[1];
+       r= mount(dev, "/", 0 /* !ro */);
+       if (r != 0)
+       {
+               fprintf(stderr, "newroot: mount failed: %s\n", strerror(errno));
+               exit(1);
+       }
+       return 0;
+}
index d07ba8499c6b6537bf87e84b7bed89cad5b75623..63354e2f8388ca3d7c0ab1a515c44deb5c117bcb 100644 (file)
@@ -24,7 +24,7 @@ LIBDRIVER = $d/libdriver/driver.o $d/libdriver/drvlib.o
 all build:     $(DRIVER)
 $(DRIVER):     $(OBJ) $(LIBDRIVER)
        $(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBDRIVER) $(LIBS)
-       install -S 256w $(DRIVER)
+       install -S 4k $(DRIVER)
 
 $(LIBDRIVER): 
        cd $d/libdriver && $(MAKE) 
index b512cc0d21375c760a27ee5849c9fbc4751b4faf..ff9f0de6a0001a7346366876b29ef420b7225b4f 100644 (file)
@@ -16,29 +16,35 @@ CFLAGS = -I$i
 LDFLAGS = -i
 LIBS = -lsys -lsysutil
 
-OBJ = memory.o
+OBJ = memory.o imgrd.o
 LIBDRIVER = $d/libdriver/driver.o
 
 
 # build local binary
 all build:     $(DRIVER)
-$(DRIVER):     $(OBJ) $(LIBDRIVER)
+
+$(DRIVER):     ramdisk_image $(OBJ) $(LIBDRIVER)
        $(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBDRIVER) $(LIBS)
        install -S 1024w $(DRIVER)
 
+imgrd.o:        ramdisk/image.c
+
 $(LIBDRIVER): 
        cd $d/libdriver && $(MAKE) 
 
+ramdisk_image:
+       cd ramdisk && make
+       binsizes big
 
 # install with other drivers
-install:       /sbin/$(DRIVER)
+install:       /sbin/$(DRIVER)
 /sbin/$(DRIVER):       $(DRIVER)
        install -o root -cs $? $@
 
 # clean up local files
 clean:
        rm -f $(DRIVER) *.o *.bak 
-
+       cd ramdisk && make clean
 
 depend: 
        /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c ../libdriver/*.c > .depend
diff --git a/drivers/memory/imgrd.c b/drivers/memory/imgrd.c
new file mode 100644 (file)
index 0000000..cc9bd85
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+Ramdisk that is part of the image
+*/
+
+#include <stddef.h>
+
+#include "local.h"
+
+unsigned char imgrd[]=
+{
+#include "ramdisk/image.c"
+};
+
+size_t imgrd_size= sizeof(imgrd);
diff --git a/drivers/memory/local.h b/drivers/memory/local.h
new file mode 100644 (file)
index 0000000..91a9ad1
--- /dev/null
@@ -0,0 +1,6 @@
+/*
+local defines and declarations 
+*/
+
+extern unsigned char imgrd[];
+extern size_t imgrd_size;
index 40b651fb336e6494a89d090f5b2a60f7103e2a90..48425130d7cf6ee6de21732ba3be7fa47b846371 100644 (file)
@@ -25,7 +25,9 @@
 
 #include "assert.h"
 
-#define NR_DEVS            6           /* number of minor devices */
+#include "local.h"
+
+#define NR_DEVS            7           /* number of minor devices */
 
 PRIVATE struct device m_geom[NR_DEVS];  /* base and size of each device */
 PRIVATE int m_seg[NR_DEVS];            /* segment index of each device */
@@ -191,6 +193,19 @@ unsigned nr_req;           /* length of request vector */
            }
            break;
 
+       case IMGRD_DEV:
+           if (position >= dv_size) return(OK);        /* check for EOF */
+           if (position + count > dv_size) count = dv_size - position;
+
+           if (opcode == DEV_GATHER) {                 /* copy actual data */
+               sys_vircopy(SELF, D, (vir_bytes)&imgrd[position],
+                       proc_nr, D, user_vir, count);
+           } else {
+               sys_vircopy(proc_nr, D, user_vir,
+                       SELF, D, (vir_bytes)&imgrd[position], count);
+           }
+           break;
+
        /* Unknown (illegal) minor device. */
        default:
            return(EINVAL);
@@ -278,6 +293,10 @@ PRIVATE void m_init()
        printf("MEM stored retrieved details as new RAM disk\n");
   }
 
+  /* Ramdisk image built into the memory driver */
+  m_geom[IMGRD_DEV].dv_base= cvul64(0);
+  m_geom[IMGRD_DEV].dv_size= cvul64(imgrd_size);
+
   /* Initialize /dev/zero. Simply write zeros into the buffer. */
   for (i=0; i<ZERO_BUF_SIZE; i++) {
        dev_zero[i] = '\0';
@@ -320,19 +339,31 @@ message *m_ptr;                           /* pointer to control message */
 
   switch (m_ptr->REQUEST) {
     case MIOCRAMSIZE: {
-       /* FS wants to create a new RAM disk with the given size. */
-       phys_bytes ramdev_size;
+       /* Someone wants to create a new RAM disk with the given size. */
+       static int first_time= 1;
+
+       u32_t ramdev_size;
        phys_bytes ramdev_base;
        message m;
        int s;
 
-       /* Only FS can create RAM disk, and only on RAM disk device. */
-       if (m_ptr->PROC_NR != FS_PROC_NR) return(EPERM);
+       /* A ramdisk can be created only once, and only on RAM disk device. */
+       if (!first_time) return(EPERM);
        if (m_ptr->DEVICE != RAM_DEV) return(EINVAL);
         if ((dv = m_prepare(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
 
+#if 0
+       ramdev_size= m_ptr->POSITION;
+#else
+       /* Get request structure */
+       s= sys_vircopy(m_ptr->PROC_NR, D, (vir_bytes)m_ptr->ADDRESS,
+               SELF, D, (vir_bytes)&ramdev_size, sizeof(ramdev_size));
+       if (s != OK)
+               return s;
+#endif
+       printf("allocating ramdisk of size 0x%x\n", ramdev_size);
+
        /* Try to allocate a piece of memory for the RAM disk. */
-       ramdev_size = m_ptr->POSITION;
         if (allocmem(ramdev_size, &ramdev_base) < 0) {
             report("MEM", "warning, allocmem failed", errno);
             return(ENOMEM);
@@ -359,6 +390,7 @@ message *m_ptr;                             /* pointer to control message */
 
        dv->dv_base = cvul64(ramdev_base);
        dv->dv_size = cvul64(ramdev_size);
+       /* first_time= 0; */
        break;
     }
     case MIOCMAP:
diff --git a/drivers/memory/ramdisk/Makefile b/drivers/memory/ramdisk/Makefile
new file mode 100644 (file)
index 0000000..209578d
--- /dev/null
@@ -0,0 +1,81 @@
+# Makefile for ramdisk image
+
+PROGRAMS=at_wini bios_wini cdprobe dev2name floppy loadramdisk newroot \
+       sh service sysenv
+
+all:   image.c
+
+clean:
+       rm -f $(PROGRAMS) bintoc image image.c
+
+image.c:       bintoc image
+       ./bintoc -o $@ image
+
+# Note for cross compilation: this executable has to be compiled for the
+# host system
+bintoc:        bintoc.c
+       $(CC) -o $@ bintoc.c
+
+image: proto mtab rc $(PROGRAMS)
+       mkfs -B1024 image proto || { rm -f image; false; }
+
+at_wini: ../../at_wini/at_wini
+       install -s ../../$@/$@ $@
+
+../../at_wini/at_wini:
+       cd ../../at_wini && make
+
+bios_wini: ../../bios_wini/bios_wini
+       install -s ../../$@/$@ $@
+
+../../bios_wini/bios_wini:
+       cd ../../bios_wini && make
+
+floppy: ../../floppy/floppy
+       install -s ../../$@/$@ $@
+
+../../floppy/floppy:
+       cd ../../floppy && make
+
+cdprobe:  ../../../commands/simple/cdprobe
+       install -s ../../../commands/simple/$@ $@
+
+../../../commands/simple/cdprobe: 
+       cd ../../../commands/simple && make cdprobe
+
+dev2name:  ../../../commands/simple/dev2name
+       install -s ../../../commands/simple/$@ $@
+
+../../../commands/simple/dev2name: 
+       cd ../../../commands/simple && make dev2name
+
+loadramdisk:  ../../../commands/simple/loadramdisk
+       install -s ../../../commands/simple/$@ $@
+
+../../../commands/simple/loadramdisk: 
+       cd ../../../commands/simple && make loadramdisk
+
+newroot:  ../../../commands/simple/newroot
+       install -s ../../../commands/simple/$@ $@
+
+../../../commands/simple/newroot: 
+       cd ../../../commands/simple && make newroot
+
+sysenv:  ../../../commands/simple/sysenv
+       install -s ../../../commands/simple/$@ $@
+
+../../../commands/simple/sysenv: 
+       cd ../../../commands/simple && make sysenv
+
+sh:    ../../../commands/ash/sh
+       install -s ../../../commands/ash/$@ $@
+
+../../../commands/ash/sh: 
+       cd ../../../commands/ash && make sh
+
+service: ../../../servers/rs/service
+       install -s ../../../servers/rs/$@ $@
+
+../../../servers/rs/service: 
+       cd ../../../servers/rs && make service
+
diff --git a/drivers/memory/ramdisk/bintoc.c b/drivers/memory/ramdisk/bintoc.c
new file mode 100644 (file)
index 0000000..36d6def
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+bintoc.c
+
+Convert a (binary) file to a series of comma separated hex values suitable
+for initializing a character array in C.
+*/
+
+#define _POSIX_C_SOURCE 2
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+char *progname;
+unsigned char buf[1024];
+
+static void fatal(char *fmt, ...);
+static void usage(void);
+
+int main(int argc, char *argv[])
+{
+       int c, i, r, first;
+       FILE *file_in, *file_out;
+       char *in_name;
+       char *o_arg;
+
+       (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
+
+       o_arg= NULL;
+       while (c= getopt(argc, argv, "?o:"), c != -1)
+       {
+               switch(c)
+               {
+               case '?': usage();
+               case 'o': o_arg= optarg; break;
+               default:  fatal("getopt failed: '%c'\n", c);
+               }
+       }
+
+       if (o_arg)
+       {
+               file_out= fopen(o_arg, "w");
+               if (file_out == NULL)
+               {
+                       fatal("unable to create '%s': %s\n",
+                               o_arg, strerror(errno));
+                       exit(1);
+               }
+       }
+       else
+               file_out= stdout;
+
+       if (optind < argc)
+       {
+               in_name= argv[optind];
+               optind++;
+               file_in= fopen(in_name, "r");
+               if (file_in == NULL)
+               {
+                       fatal("unable to open '%s': %s",
+                               in_name, strerror(errno));
+               }
+       }
+       else
+       {
+               in_name= "(stdin)";
+               file_in= stdin;
+       }
+
+       if (optind != argc)
+               usage();
+
+       first= 1;
+       for (;;)
+       {
+               r= fread(buf, 1, sizeof(buf), file_in);
+               if (r == 0)
+                       break;
+               for (i= 0; i<r; i++)
+               {
+                       if ((i % 8) == 0)
+                       {
+                               if (first)
+                               {
+                                       fprintf(file_out, "\t");
+                                       first= 0;
+                               }
+                               else
+                                       fprintf(file_out, ",\n\t");
+                       }
+                       else
+                               fprintf(file_out, ", ");
+                       fprintf(file_out, "0x%02x", buf[i]);
+               }
+       }
+
+       if (ferror(file_in))
+       {
+               fatal("read error on %s: %s\n",
+                       in_name, strerror(errno));
+       }
+       fprintf(file_out, "\n");
+
+       exit(0);
+}
+
+static void fatal(char *fmt, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "%s: ", progname);
+
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+
+       fprintf(stderr, "\n");
+
+       exit(1);
+}
+
+static void usage(void)
+{
+       fprintf(stderr, "Usage: bintoc [-o <out-file>] [<in-file>]\n");
+       exit(1);
+}
diff --git a/drivers/memory/ramdisk/mtab b/drivers/memory/ramdisk/mtab
new file mode 100755 (executable)
index 0000000..8b92699
--- /dev/null
@@ -0,0 +1 @@
+/dev/imgrd / 3 rw
diff --git a/drivers/memory/ramdisk/proto b/drivers/memory/ramdisk/proto
new file mode 100644 (file)
index 0000000..de7de55
--- /dev/null
@@ -0,0 +1,66 @@
+boot 
+200 100
+d--755 0 0
+       bin d--755 0 0
+               at_wini ---755 0 0 at_wini
+               bios_wini ---755 0 0 bios_wini
+               cdprobe ---755 0 0 cdprobe
+               dev2name ---755 0 0 dev2name
+               floppy ---755 0 0 floppy
+               loadramdisk ---755 0 0 loadramdisk
+               newroot ---755 0 0 newroot
+               sh ---755 0 0 sh
+               service ---755 0 0 service
+               sysenv ---755 0 0 sysenv
+       $
+       dev d--755 0 0
+               c0d0 b--222 0 0 3 0
+               c0d1 b--222 0 0 3 5
+               c0d2 b--222 0 0 3 10
+               c0d3 b--222 0 0 3 15
+               c0d0p0 b--222 0 0 3 1
+               c0d0p1 b--222 0 0 3 2
+               c0d0p2 b--222 0 0 3 3
+               c0d0p3 b--222 0 0 3 4
+               c0d1p0 b--222 0 0 3 6
+               c0d1p1 b--222 0 0 3 7
+               c0d1p2 b--222 0 0 3 8
+               c0d1p3 b--222 0 0 3 9
+               c0d2p0 b--222 0 0 3 11
+               c0d2p1 b--222 0 0 3 12
+               c0d2p2 b--222 0 0 3 13
+               c0d2p3 b--222 0 0 3 14
+               c0d3p0 b--222 0 0 3 16
+               c0d3p1 b--222 0 0 3 17
+               c0d3p2 b--222 0 0 3 18
+               c0d3p3 b--222 0 0 3 19
+               c0d0p0s0 b--222 0 0 3 128
+               c0d0p1s0 b--222 0 0 3 132
+               c0d0p2s0 b--222 0 0 3 136
+               c0d0p3s0 b--222 0 0 3 140
+               c0d1p0s0 b--222 0 0 3 144
+               c0d1p1s0 b--222 0 0 3 148
+               c0d1p2s0 b--222 0 0 3 152
+               c0d1p3s0 b--222 0 0 3 156
+               c0d2p0s0 b--222 0 0 3 160
+               c0d2p1s0 b--222 0 0 3 164
+               c0d2p2s0 b--222 0 0 3 168
+               c0d2p3s0 b--222 0 0 3 172
+               c0d3p0s0 b--222 0 0 3 176
+               c0d3p1s0 b--222 0 0 3 180
+               c0d3p2s0 b--222 0 0 3 184
+               c0d3p3s0 b--222 0 0 3 188
+               fd0 b--222 0 0 2 0
+               fd0p0 b--222 0 0 2 112
+               fd0p1 b--222 0 0 2 116
+               fd0p2 b--222 0 0 2 120
+               fd0p3 b--222 0 0 2 124
+               log c--222 0 0 4 15
+               null c--666 0 0 1 3
+               ram b--600 0 0 1 0
+       $
+       etc d--755 0 0
+               mtab ---644 0 0 mtab
+               rc ---755 0 0 rc
+       $
+$
diff --git a/drivers/memory/ramdisk/rc b/drivers/memory/ramdisk/rc
new file mode 100644 (file)
index 0000000..2aefa96
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+set -e
+/bin/service up /bin/floppy -dev /dev/fd0
+if [ X`/bin/sysenv bios_wini` = Xyes ]
+then
+       echo Using bios_wini.
+       /bin/service up /bin/bios_wini -dev /dev/c0d0
+else
+       /bin/service up /bin/at_wini -dev /dev/c0d0
+fi
+
+rootdev=`sysenv rootdev` || echo 'No rootdev?'
+rootdevname=`/bin/dev2name "$rootdev"` ||
+       { echo 'No device name for root device'; exit 1; }
+
+if sysenv cdproberoot >/dev/null
+then
+       echo 
+       echo 'Looking for boot CD. This may take a minute.'
+       echo 'Please ignore any error messages.'
+       echo
+       cddev=`cdprobe` || { echo 'No CD found'; exit 1; }
+       export cddev
+       echo "Loading ramdisk from ${cddev}p1"
+       loadramdisk "$cddev"p1
+elif [ "$rootdevname" = "/dev/ram" ]
+then
+       ramimagedev=`sysenv ramimagedev` ||
+               { echo 'ramimagedev not found'; exit 1; }
+       ramimagename=`/bin/dev2name "$ramimagedev"` ||
+               { echo 'No device name for ramimagedev'; exit 1; }
+       echo "Loading ramdisk from $ramimagename"
+       loadramdisk "$ramimagename"
+fi
+echo "Root device name is $rootdevname"
+/bin/newroot "$rootdevname"
+exec /bin/sh /etc/rc start
index 3b229155bd15794cbcab9d832b17ec93cc1fe2c7..8e21938d1831ac6bed7e493c30e76e7d6a1aaffb 100644 (file)
@@ -1,7 +1,10 @@
 /usr/lib/cpp.ansi 1416004
-/usr/lib/cv 1738570
-/usr/lib/em_cemcom.ansi 4683676
-/usr/lib/em_led 3078088
+/usr/lib/cv 3738570
+/usr/lib/em_cemcom.ansi 10683676
+/usr/lib/em_led 4078088
 /usr/lib/em_opt 1370162
 /usr/lib/i386/as 1239922
 /usr/lib/i386/cg 1285513
+/usr/bin/make 2000000
+/bin/sh        1000000
+/usr/bin/lex 1000000
diff --git a/etc/rc b/etc/rc
index ade6493f10b3b860cb40bd2694fdb27ac102aed9..c92d61840431c0b28c121036c8ddccbe02e2adec 100755 (executable)
--- a/etc/rc
+++ b/etc/rc
@@ -86,10 +86,10 @@ start)
     # where it is based on sysenv (set by FS when probing for CD).
     if [ "$bootcd" = 1 ]
     then       
-               imagedev="`/bin/sysenv cdproberoot`"
-               usrdev="`expr $imagedev + 1`"
+               #imagedev="`/bin/sysenv cdproberoot`"
+               #usrdev="`expr $imagedev + 1`"
                usr_roflag="-r"
-               usr="`/bin/dev2name $usrdev`"
+               usr="$cddev"p2
                echo "Setting /usr on cd is $usr"
     fi
  
index c657576422dadefe1edddc71f71a0839b1ce4b6c..484179750c4373bfdba2ea59a28f577fe3d6a627 100755 (executable)
 #define MEM_PROC_NR      3     /* memory driver (RAM disk, null, etc.) */
 #define LOG_PROC_NR      4     /* log device driver */
 #define TTY_PROC_NR      5     /* terminal (TTY) driver */
-#define DRVR_PROC_NR      6    /* device driver for boot medium */
-#define DS_PROC_NR       7     /* data store server */
-#define PCI_PROC_NR       8    /* driver for PCI controllers */
-#define INIT_PROC_NR     9     /* init -- goes multiuser */
+#define DS_PROC_NR       6     /* data store server */
+#define PCI_PROC_NR       7    /* driver for PCI controllers */
+#define INIT_PROC_NR     8     /* init -- goes multiuser */
 
 /* Number of processes contained in the system image. */
 #define NR_BOOT_PROCS  (NR_TASKS + INIT_PROC_NR + 1)
index e985aebcd1b84aee7f0ef0ce4fc4f817754d3fd9..8b7d3121e06798774827c9657c157c88bda147cc 100644 (file)
@@ -41,12 +41,14 @@ extern struct dmap {
 #  define NULL_DEV                3    /* minor device for /dev/null */
 #  define BOOT_DEV                4    /* minor device for /dev/boot */
 #  define ZERO_DEV                5    /* minor device for /dev/zero */
+#  define IMGRD_DEV               6    /* minor device for /dev/imgrd */
 
 #define CTRLR(n) ((n)==0 ? 3 : (8 + 2*((n)-1)))        /* magic formula */
 
 /* Full device numbers that are special to the boot monitor and FS. */
 #  define DEV_RAM            0x0100    /* device number of /dev/ram */
 #  define DEV_BOOT           0x0104    /* device number of /dev/boot */
+#  define DEV_IMGRD          0x0106    /* device number of /dev/imgrd */
 
 #define FLOPPY_MAJOR              2    /* major device for floppy disks */
 #define TTY_MAJOR                 4    /* major device for ttys */
index a937c8f3c9eef8a0bf3c74525c08c46adbb4d97a..cf23259fa3683929ab152271e408750cb7be4db4 100755 (executable)
@@ -107,7 +107,9 @@ PUBLIC struct boot_image image[] = {
  { TTY_PROC_NR,   0, SRV_F,  4,      1, 0,     SRV_T, SYS_M, TTY_C, "tty"   },
  { MEM_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, MEM_C, "memory"},
  { LOG_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, DRV_C, "log"   },
+#if 0
  { DRVR_PROC_NR,  0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, DRV_C, "driver"},
+#endif
  { PCI_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, PCI_C, "pci"},
  { INIT_PROC_NR,  0, USR_F,  8, USER_Q, 0,     USR_T, USR_M,     0, "init"  },
 };
index 1e114cb63c6ef19909cb0af5efa1db78a2dd133e..ecb8866ab8810d6b6915493977b286a7c6cb61b6 100644 (file)
@@ -185,6 +185,7 @@ PUBLIC void build_dmap()
       }
   }
 
+#if 0
   /* Get settings of 'controller' and 'driver' at the boot monitor. */
   if ((s = env_get_param("label", driver, sizeof(driver))) != OK) 
       panic(__FILE__,"couldn't get boot monitor parameter 'driver'", s);
@@ -209,6 +210,7 @@ PUBLIC void build_dmap()
       panic(__FILE__,"map_driver failed",s);
   printf("Boot medium driver: %s driver mapped onto controller %s.\n",
       driver, controller);
+#endif
 }
 
 /*===========================================================================*
index f458252b6bc46af9d41017c44eec787396764abc..7e318c602024eb96dc892c3bc7cbb2753a6bfbf0 100644 (file)
@@ -277,6 +277,7 @@ PRIVATE void load_ram(void)
 
   /* Get some boot environment variables. */
   root_dev = igetenv("rootdev", 0);
+  root_dev = DEV_IMGRD;
   image_dev = igetenv("ramimagedev", 0);
   ram_size_kb = igetenv("ramsize", 0);
 
@@ -284,6 +285,7 @@ PRIVATE void load_ram(void)
   if (dev_open(root_dev, FS_PROC_NR, R_BIT|W_BIT) != OK)
        panic(__FILE__,"Cannot open root device",NO_NUM);
 
+#if 0
   /* If we must initialize a ram disk, get details from the image device. */
   if (root_dev == DEV_RAM) {
        u32_t fsmax, probedev;
@@ -329,6 +331,7 @@ PRIVATE void load_ram(void)
        if (ram_size_kb*1024 > fsmax*sp->s_block_size)
                ram_size_kb = fsmax*sp->s_block_size/1024;
   }
+#endif
 
   /* Tell RAM driver how big the RAM disk must be. */
   m_out.m_type = DEV_IOCTL;
@@ -336,6 +339,7 @@ PRIVATE void load_ram(void)
   m_out.DEVICE = RAM_DEV;
   m_out.REQUEST = MIOCRAMSIZE;                 /* I/O control to use */
   m_out.POSITION = (ram_size_kb * 1024);       /* request in bytes */
+#if 0
   if ((s=sendrec(MEM_PROC_NR, &m_out)) != OK)
        panic("FS","sendrec from MEM failed", s);
   else if (m_out.REP_STATUS != OK) {
@@ -347,6 +351,7 @@ PRIVATE void load_ram(void)
                panic(__FILE__,"can't set RAM disk size", m_out.REP_STATUS);
        }
   }
+#endif
 
 #if ENABLE_CACHE2
   /* The RAM disk is a second level block cache while not otherwise used. */
@@ -357,6 +362,8 @@ PRIVATE void load_ram(void)
   if (root_dev != DEV_RAM)
        return;
 
+#if 0
+
   /* Copy the blocks one at a time from the image to the RAM disk. */
   printf("Loading RAM disk onto /dev/ram:\33[23CLoaded:    0 KB");
 
@@ -424,6 +431,7 @@ PRIVATE void load_ram(void)
        sbbuf, SUPER_BLOCK_BYTES, _MIN_BLOCK_SIZE, 0) != _MIN_BLOCK_SIZE) {
        printf("WARNING: ramdisk write for resizing failed\n");
   }
+#endif
 }
 
 /*===========================================================================*
index 77bc2d2be22e6784ae3f4c869b797fd1bbb3682d..8609a35f65a07b3b148d052cbcaa2d0df9551812 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "fs.h"
 #include <fcntl.h>
+#include <string.h>
 #include <minix/com.h>
 #include <sys/stat.h>
 #include "buf.h"
@@ -16,6 +17,9 @@
 #include "param.h"
 #include "super.h"
 
+/* Allow the root to be replaced before the first 'real' mount. */
+PRIVATE int allow_newroot= 1;
+
 FORWARD _PROTOTYPE( dev_t name_to_dev, (char *path)                    );
 
 /*===========================================================================*
@@ -30,7 +34,8 @@ PUBLIC int do_mount()
   dev_t dev;
   mode_t bits;
   int rdir, mdir;              /* TRUE iff {root|mount} file is dir */
-  int r, found;
+  int i, r, found;
+  struct fproc *tfp;
 
   /* Only the super-user may do MOUNT. */
   if (!super_user) return(EPERM);
@@ -43,10 +48,87 @@ PUBLIC int do_mount()
   sp = NIL_SUPER;
   found = FALSE;
   for (xp = &super_block[0]; xp < &super_block[NR_SUPERS]; xp++) {
-       if (xp->s_dev == dev) found = TRUE;     /* is it mounted already? */
+       if (xp->s_dev == dev)
+       {
+               /* is it mounted already? */
+               found = TRUE;
+               sp= xp;
+               break;
+       }
        if (xp->s_dev == NO_DEV) sp = xp;       /* record free slot */
   }
-  if (found) return(EBUSY);    /* already mounted */
+  if (found)
+  {
+       printf(
+"do_mount: s_imount = 0x%x (%x, %d), s_isup = 0x%x (%x, %d), fp_rootdir = 0x%x\n",
+               xp->s_imount, xp->s_imount->i_dev, xp->s_imount->i_num,
+               xp->s_isup, xp->s_isup->i_dev, xp->s_isup->i_num,
+               fproc[FS_PROC_NR].fp_rootdir);
+       /* It is possible that we have an old root lying around that 
+        * needs to be remounted.
+        */
+       if (xp->s_imount != xp->s_isup ||
+               xp->s_isup == fproc[FS_PROC_NR].fp_rootdir)
+       {
+               /* Normally, s_imount refers to the mount point. For a root
+                * filesystem, s_imount is equal to the root inode. We assume
+                * that the root of FS is always the real root. If the two
+                * inodes are different or if the root of FS is equal two the
+                * root of the filesystem we found, we found a filesystem that
+                * is in use.
+                */
+               return(EBUSY);  /* already mounted */
+       }
+
+       if (root_dev == xp->s_dev)
+       {
+               panic("fs", "inconsistency remounting old root",
+                       NO_NUM);
+       }
+
+       /* Now get the inode of the file to be mounted on. */
+       if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
+               return(err_code);
+       }
+
+       if ( (rip = eat_path(user_path)) == NIL_INODE) {
+               return(err_code);
+       }
+
+       r = OK;
+
+       /* It may not be special. */
+       bits = rip->i_mode & I_TYPE;
+       if (bits == I_BLOCK_SPECIAL || bits == I_CHAR_SPECIAL)
+               r = ENOTDIR;
+
+       /* Get the root inode of the mounted file system. */
+       root_ip= sp->s_isup;
+
+       /* File types of 'rip' and 'root_ip' may not conflict. */
+       if (r == OK) {
+               mdir = ((rip->i_mode & I_TYPE) == I_DIRECTORY); 
+                                               /* TRUE iff dir */
+               rdir = ((root_ip->i_mode & I_TYPE) == I_DIRECTORY);
+               if (!mdir && rdir) r = EISDIR;
+       }
+
+       /* If error, return the mount point. */
+       if (r != OK) {
+               put_inode(rip);
+               return(r);
+       }
+
+       /* Nothing else can go wrong.  Perform the mount. */
+       rip->i_mount = I_MOUNT; /* this bit says the inode is
+                                * mounted on
+                                */
+       put_inode(sp->s_imount);
+       sp->s_imount = rip;
+       sp->s_rd_only = m_in.rd_only;
+       allow_newroot= 0;               /* The root is now fixed */
+       return(OK);
+  }
   if (sp == NIL_SUPER) return(ENFILE); /* no super block available */
 
   /* Open the device the file system lives on. */
@@ -74,6 +156,58 @@ PUBLIC int do_mount()
        sp->s_dev = NO_DEV;
        return(err_code);
   }
+
+  if (strcmp(user_path, "/") == 0 && allow_newroot)
+  {
+       printf("Replacing root\n");
+
+       /* Get the root inode of the mounted file system. */
+       if ( (root_ip = get_inode(dev, ROOT_INODE)) == NIL_INODE) r = err_code;
+       if (root_ip != NIL_INODE && root_ip->i_mode == 0) {
+               r = EINVAL;
+       }
+
+       /* If error, return the super block and both inodes; release the
+        * maps.
+        */
+       if (r != OK) {
+               put_inode(root_ip);
+               (void) do_sync();
+               invalidate(dev);
+               dev_close(dev);
+               sp->s_dev = NO_DEV;
+               return(r);
+       }
+
+       /* Nothing else can go wrong.  Perform the mount. */
+       sp->s_imount = root_ip;
+       dup_inode(root_ip);
+       sp->s_isup = root_ip;
+       sp->s_rd_only = m_in.rd_only;
+       root_dev= dev;
+
+       /* Replace all root and working directories */
+       for (i= 0, tfp= fproc; i<NR_PROCS; i++, tfp++)
+       {
+               if (tfp->fp_pid == PID_FREE)
+                       continue;
+               if (tfp->fp_rootdir == NULL)
+                       panic("fs", "do_mount: null rootdir", i);
+               put_inode(tfp->fp_rootdir);
+               dup_inode(root_ip);
+               tfp->fp_rootdir= root_ip;
+
+               if (tfp->fp_workdir == NULL)
+                       panic("fs", "do_mount: null workdir", i);
+               put_inode(tfp->fp_workdir);
+               dup_inode(root_ip);
+               tfp->fp_workdir= root_ip;
+       }
+
+       /* Leave the old filesystem lying around. */
+       return(OK);
+  }
+
   if ( (rip = eat_path(user_path)) == NIL_INODE) {
        dev_close(dev);
        sp->s_dev = NO_DEV;
@@ -120,6 +254,7 @@ PUBLIC int do_mount()
   sp->s_imount = rip;
   sp->s_isup = root_ip;
   sp->s_rd_only = m_in.rd_only;
+  allow_newroot= 0;            /* The root is now fixed */
   return(OK);
 }
 
index 51bdc3897038f995e644d7502c49b1cf27ab5d15..18b1f9b21e763a3fd7049552b6e2205e0d019872 100644 (file)
@@ -299,19 +299,18 @@ char string[NAME_MAX];            /* component name to look for */
   if (rip->i_num == ROOT_INODE)
        if (dirp->i_num == ROOT_INODE) {
            if (string[1] == '.') {
-               for (sp = &super_block[1]; sp < &super_block[NR_SUPERS]; sp++){
-                       if (sp->s_dev == rip->i_dev) {
-                               /* Release the root inode.  Replace by the
-                                * inode mounted on. Update parent.
-                                */
-                               put_inode(rip);
-                               put_inode(dirp);
-                               mnt_dev = sp->s_imount->i_dev;
-                               inumb = (int) sp->s_imount->i_num;
-                               dirp = *pdirp = get_inode(mnt_dev, inumb);
-                               rip = advance(pdirp, string);
-                               break;
-                       }
+               sp= rip->i_sp;
+               if (sp->s_imount != sp->s_isup)
+               {
+                       /* Release the root inode.  Replace by the
+                        * inode mounted on. Update parent.
+                        */
+                       put_inode(rip);
+                       put_inode(dirp);
+                       mnt_dev = sp->s_imount->i_dev;
+                       inumb = (int) sp->s_imount->i_num;
+                       dirp = *pdirp = get_inode(mnt_dev, inumb);
+                       rip = advance(pdirp, string);
                }
            }
        }
index 8809ba4f68dbeb9f3c75f2d80079636cdf287e18..de7eae8734ede6e6bf8df44511baa5702d2a3da1 100755 (executable)
@@ -19,13 +19,8 @@ PROGRAMS=    ../kernel/kernel \
        ../drivers/tty/tty \
        ../drivers/memory/memory \
        ../drivers/log/log \
-       AT:../drivers/at_wini/at_wini \
-       BIOS:../drivers/bios_wini/bios_wini \
-       FLOPPY:../drivers/floppy/floppy \
        ../drivers/pci/pci \
-       ../servers/init/init \
-#      bootdev.img
-
+       ../servers/init/init
 
 usage: 
        @echo " " >&2