do awk '{ print "chmem =" $2 " " $1 " >/dev/null 2>&1 "}'
done | /bin/sh
fi
+exit 0
calendar \
cat \
cdiff \
+ cdprobe \
cgrep \
chmem \
chmod \
last \
leave \
life \
+ loadramdisk \
login \
look \
lp \
mount \
mt \
nm \
+ newroot \
nonamed \
nice \
od \
$(CCLD) -o $@ $?
@install -S 28kw $@
+cdprobe: cdprobe.c
+ $(CCLD) -o $@ $?
+ @install -S 28kw $@
+
cgrep: cgrep.c
$(CCLD) -o $@ $?
@install -S 5kw $@
$(CCLD) -o $@ $? -lcurses
@install -S 15kw $@
+loadramdisk: loadramdisk.c
+ $(CCLD) -o $@ $?
+ install -S 4kw $@
+
login: login.c
$(CCLD) -o $@ $?
install -S 4kw $@
$(CCLD) -o $@ $?
@install -S 4kw $@
+newroot: newroot.c
+ $(CCLD) -o $@ $?
+ @install -S 32kw $@
+
nm: nm.c
$(CCLD) -o $@ $?
@install -S 32kw $@
/usr/bin/calendar \
/usr/bin/cat \
/usr/bin/cdiff \
+ /usr/bin/cdprobe \
/usr/bin/cgrep \
/usr/bin/chmem \
/usr/bin/chmod \
/usr/bin/uptime \
/usr/bin/leave \
/usr/bin/life \
+ /usr/bin/loadramdisk \
/usr/bin/login \
/usr/bin/look \
/usr/bin/lp \
/usr/bin/modem \
/usr/bin/mount \
/usr/bin/mt \
+ /usr/bin/newroot \
/usr/bin/nm \
/usr/bin/nice \
/usr/bin/nonamed \
/usr/bin/cdiff: cdiff
install -cs -o bin $? $@
+/usr/bin/cdprobe: cdprobe
+ install -cs -o bin $? $@
+
/usr/bin/cgrep: cgrep
install -cs -o bin $? $@
/usr/bin/life: life
install -cs -o bin $? $@
+/usr/bin/loadramdisk: loadramdisk
+ install -cs -o bin $? $@
+
/usr/bin/login: login
install -cs -o bin $? $@
/usr/bin/mt: mt
install -cs -o bin $? $@
+/usr/bin/newroot: newroot
+ install -cs -o bin $? $@
+
/usr/bin/nm: nm
install -cs -o bin $? $@
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+/*
+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;
+}
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) {
{
/* 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);
--- /dev/null
+/*
+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;
+}
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)
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
--- /dev/null
+/*
+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);
--- /dev/null
+/*
+local defines and declarations
+*/
+
+extern unsigned char imgrd[];
+extern size_t imgrd_size;
#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 */
}
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);
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';
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);
dv->dv_base = cvul64(ramdev_base);
dv->dv_size = cvul64(ramdev_size);
+ /* first_time= 0; */
break;
}
case MIOCMAP:
--- /dev/null
+# 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
+
--- /dev/null
+/*
+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);
+}
--- /dev/null
+/dev/imgrd / 3 rw
--- /dev/null
+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
+ $
+$
--- /dev/null
+#!/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
/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
# 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
#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)
# 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 */
{ 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" },
};
}
}
+#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);
panic(__FILE__,"map_driver failed",s);
printf("Boot medium driver: %s driver mapped onto controller %s.\n",
driver, controller);
+#endif
}
/*===========================================================================*
/* 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);
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;
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;
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) {
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. */
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");
sbbuf, SUPER_BLOCK_BYTES, _MIN_BLOCK_SIZE, 0) != _MIN_BLOCK_SIZE) {
printf("WARNING: ramdisk write for resizing failed\n");
}
+#endif
}
/*===========================================================================*
#include "fs.h"
#include <fcntl.h>
+#include <string.h>
#include <minix/com.h>
#include <sys/stat.h>
#include "buf.h"
#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) );
/*===========================================================================*
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);
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. */
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;
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);
}
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);
}
}
}
../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