From c3a88d15d8a253f9a604c83a0d5c10c71a2ade09 Mon Sep 17 00:00:00 2001 From: Philip Homburg Date: Wed, 15 Feb 2006 11:18:21 +0000 Subject: [PATCH] Initial root filesystem is now on a ramdisk that is part of the image. --- commands/scripts/binsizes.sh | 1 + commands/simple/Makefile | 27 ++++++ commands/simple/cdprobe.c | 130 +++++++++++++++++++++++++++++ commands/simple/loadramdisk.c | 126 ++++++++++++++++++++++++++++ commands/simple/mkfs.c | 21 ++++- commands/simple/newroot.c | 31 +++++++ drivers/bios_wini/Makefile | 2 +- drivers/memory/Makefile | 14 +++- drivers/memory/imgrd.c | 14 ++++ drivers/memory/local.h | 6 ++ drivers/memory/memory.c | 44 ++++++++-- drivers/memory/ramdisk/Makefile | 81 ++++++++++++++++++ drivers/memory/ramdisk/bintoc.c | 129 +++++++++++++++++++++++++++++ drivers/memory/ramdisk/mtab | 1 + drivers/memory/ramdisk/proto | 66 +++++++++++++++ drivers/memory/ramdisk/rc | 37 +++++++++ etc/binary_sizes.big | 9 +- etc/rc | 6 +- include/minix/com.h | 7 +- include/minix/dmap.h | 2 + kernel/table.c | 2 + servers/fs/dmap.c | 2 + servers/fs/main.c | 8 ++ servers/fs/mount.c | 141 +++++++++++++++++++++++++++++++- servers/fs/path.c | 25 +++--- tools/Makefile | 7 +- 26 files changed, 894 insertions(+), 45 deletions(-) create mode 100644 commands/simple/cdprobe.c create mode 100644 commands/simple/loadramdisk.c create mode 100644 commands/simple/newroot.c create mode 100644 drivers/memory/imgrd.c create mode 100644 drivers/memory/local.h create mode 100644 drivers/memory/ramdisk/Makefile create mode 100644 drivers/memory/ramdisk/bintoc.c create mode 100755 drivers/memory/ramdisk/mtab create mode 100644 drivers/memory/ramdisk/proto create mode 100644 drivers/memory/ramdisk/rc diff --git a/commands/scripts/binsizes.sh b/commands/scripts/binsizes.sh index bc6716ddc..36ffcd5b1 100644 --- a/commands/scripts/binsizes.sh +++ b/commands/scripts/binsizes.sh @@ -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 diff --git a/commands/simple/Makefile b/commands/simple/Makefile index d58d2b045..6d7afcec5 100755 --- a/commands/simple/Makefile +++ b/commands/simple/Makefile @@ -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 index 000000000..79562696b --- /dev/null +++ b/commands/simple/cdprobe.c @@ -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 +#include +#include +#include +#include +#include + +#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 index 000000000..60fcfeca8 --- /dev/null +++ b/commands/simple/loadramdisk.c @@ -0,0 +1,126 @@ +/* +loadramdisk.c + +Copy a device or file specified as argument to /dev/ram +*/ + +#include +#include +#include +#include +#include +#include +#include + +#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 \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; +} diff --git a/commands/simple/mkfs.c b/commands/simple/mkfs.c index 9613e87d1..3f0d4d307 100755 --- a/commands/simple/mkfs.c +++ b/commands/simple/mkfs.c @@ -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 index 000000000..4a9a04756 --- /dev/null +++ b/commands/simple/newroot.c @@ -0,0 +1,31 @@ +/* +newroot.c + +Replace the current root with a new one +*/ + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int r; + char *dev; + + if (argc != 2) + { + fprintf(stderr, "Usage: newroot \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; +} diff --git a/drivers/bios_wini/Makefile b/drivers/bios_wini/Makefile index d07ba8499..63354e2f8 100644 --- a/drivers/bios_wini/Makefile +++ b/drivers/bios_wini/Makefile @@ -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) diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index b512cc0d2..ff9f0de6a 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -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 index 000000000..cc9bd8518 --- /dev/null +++ b/drivers/memory/imgrd.c @@ -0,0 +1,14 @@ +/* +Ramdisk that is part of the image +*/ + +#include + +#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 index 000000000..91a9ad16a --- /dev/null +++ b/drivers/memory/local.h @@ -0,0 +1,6 @@ +/* +local defines and declarations +*/ + +extern unsigned char imgrd[]; +extern size_t imgrd_size; diff --git a/drivers/memory/memory.c b/drivers/memory/memory.c index 40b651fb3..48425130d 100644 --- a/drivers/memory/memory.c +++ b/drivers/memory/memory.c @@ -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; iREQUEST) { 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 index 000000000..209578d71 --- /dev/null +++ b/drivers/memory/ramdisk/Makefile @@ -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 index 000000000..36d6def6a --- /dev/null +++ b/drivers/memory/ramdisk/bintoc.c @@ -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 +#include +#include +#include +#include +#include + +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] []\n"); + exit(1); +} diff --git a/drivers/memory/ramdisk/mtab b/drivers/memory/ramdisk/mtab new file mode 100755 index 000000000..8b92699c0 --- /dev/null +++ b/drivers/memory/ramdisk/mtab @@ -0,0 +1 @@ +/dev/imgrd / 3 rw diff --git a/drivers/memory/ramdisk/proto b/drivers/memory/ramdisk/proto new file mode 100644 index 000000000..de7de55b4 --- /dev/null +++ b/drivers/memory/ramdisk/proto @@ -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 index 000000000..2aefa961e --- /dev/null +++ b/drivers/memory/ramdisk/rc @@ -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 diff --git a/etc/binary_sizes.big b/etc/binary_sizes.big index 3b229155b..8e21938d1 100644 --- a/etc/binary_sizes.big +++ b/etc/binary_sizes.big @@ -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 ade6493f1..c92d61840 100755 --- 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 diff --git a/include/minix/com.h b/include/minix/com.h index c65757642..484179750 100755 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -37,10 +37,9 @@ #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) diff --git a/include/minix/dmap.h b/include/minix/dmap.h index e985aebcd..8b7d3121e 100644 --- a/include/minix/dmap.h +++ b/include/minix/dmap.h @@ -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 */ diff --git a/kernel/table.c b/kernel/table.c index a937c8f3c..cf23259fa 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -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" }, }; diff --git a/servers/fs/dmap.c b/servers/fs/dmap.c index 1e114cb63..ecb8866ab 100644 --- a/servers/fs/dmap.c +++ b/servers/fs/dmap.c @@ -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 } /*===========================================================================* diff --git a/servers/fs/main.c b/servers/fs/main.c index f458252b6..7e318c602 100644 --- a/servers/fs/main.c +++ b/servers/fs/main.c @@ -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 } /*===========================================================================* diff --git a/servers/fs/mount.c b/servers/fs/mount.c index 77bc2d2be..8609a35f6 100644 --- a/servers/fs/mount.c +++ b/servers/fs/mount.c @@ -7,6 +7,7 @@ #include "fs.h" #include +#include #include #include #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; ifp_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); } diff --git a/servers/fs/path.c b/servers/fs/path.c index 51bdc3897..18b1f9b21 100644 --- a/servers/fs/path.c +++ b/servers/fs/path.c @@ -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); } } } diff --git a/tools/Makefile b/tools/Makefile index 8809ba4f6..de7eae873 100755 --- a/tools/Makefile +++ b/tools/Makefile @@ -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 -- 2.44.0