summaryrefslogtreecommitdiff
path: root/sys/stand
diff options
context:
space:
mode:
authorTobias Weingartner <weingart@cvs.openbsd.org>1997-03-31 03:12:20 +0000
committerTobias Weingartner <weingart@cvs.openbsd.org>1997-03-31 03:12:20 +0000
commitdb37cd8003c371210064ba9f9a9c279f13a175d2 (patch)
tree95a740b2174d900a416d0fd7fac0895c9e3972ab /sys/stand
parent1dc40aae41ae95a97b3d0955f1cf85385b6de1a4 (diff)
Initial /boot stuff (from Mickey)
Diffstat (limited to 'sys/stand')
-rw-r--r--sys/stand/boot/boot.c130
-rw-r--r--sys/stand/boot/cmd.c325
-rw-r--r--sys/stand/boot/cmd.h53
3 files changed, 508 insertions, 0 deletions
diff --git a/sys/stand/boot/boot.c b/sys/stand/boot/boot.c
new file mode 100644
index 00000000000..5770f608d53
--- /dev/null
+++ b/sys/stand/boot/boot.c
@@ -0,0 +1,130 @@
+/* $OpenBSD: boot.c,v 1.2 1997/03/31 03:12:03 weingart Exp $ */
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/stat.h>
+#include <a.out.h>
+#include <sys/disklabel.h>
+#include <libsa.h>
+#include "cmd.h"
+
+/*
+ * Boot program, loaded by boot block from remaing 7.5K of boot area.
+ * Sifts through disklabel and attempts to load an program image of
+ * a standalone program off the disk. If keyboard is hit during load,
+ * or if an error is encounter, try alternate files.
+ */
+
+char *kernels[] = {
+ "bsd", "bsd.gz",
+ "obsd", "obsd.gz",
+ "bsd.old", "bsd.old.gz",
+ NULL
+};
+
+int retry = 0;
+extern char version[];
+extern dev_t bootdev;
+extern int boothowto;
+int cnvmem, extmem, probemem;
+
+void boot ();
+struct cmd_state cmd;
+
+/*
+ * Boot program... loads /boot out of filesystem indicated by arguements.
+ * We assume an autoboot unless we detect a misconfiguration.
+ */
+void
+boot()
+{
+ register char *bootfile = kernels[0];
+ register int i;
+
+
+ /* Get memory size */
+ cnvmem = memsize(0);
+ extmem = memsize(1);
+ gateA20(1);
+ probemem = memprobe();
+
+
+ /* XXX init cmd here to cut on .data !!! */
+ strncpy(cmd.bootdev,
+#ifdef _TEST
+ "/dev/rfd0a",
+#else
+ "fd(0,a)",
+#endif
+ sizeof(cmd.bootdev));
+ cmd.image[0] = '\0';
+ cmd.cwd[0] = '/';
+ cmd.cwd[1] = '\0';
+ cmd.addr = (void *)0x100000;
+ cmd.timeout = 50000;
+
+ printf("\n>> OpenBSD BOOT: %d/%d (%d) k [%s]\n",
+ cnvmem, extmem, probemem, version);
+
+ for (i = 0;;) {
+
+ strncpy(cmd.image, bootfile, sizeof(cmd.image));
+
+ do {
+ printf("boot> ");
+ } while(!getcmd(&cmd) && !execmd(&cmd));
+
+ sprintf(cmd.path, "%s%s%s", cmd.bootdev, cmd.cwd, bootfile);
+ printf("\nbooting %s: ", cmd.path);
+ exec (cmd.path, cmd.addr, boothowto);
+
+ if(kernels[++i] == NULL)
+ bootfile = kernels[i=0];
+ else
+ bootfile = kernels[i];
+
+ cmd.timeout += 20;
+
+ printf(" failed(%d)\nwill try %s\n", errno, bootfile);
+ }
+}
+
+#ifdef _TEST
+int
+main()
+{
+ boot();
+ return 0;
+}
+#endif
diff --git a/sys/stand/boot/cmd.c b/sys/stand/boot/cmd.c
new file mode 100644
index 00000000000..f6d2aa39a9f
--- /dev/null
+++ b/sys/stand/boot/cmd.c
@@ -0,0 +1,325 @@
+/* $OpenBSD: cmd.c,v 1.1 1997/03/31 03:12:03 weingart Exp $ */
+
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <string.h>
+#include <libsa.h>
+#include "cmd.h"
+
+static struct cmd_table {
+ char *cmd_name;
+ int cmd_id;
+} cmd_table[] = {
+ {"addr", CMD_ADDR},
+ {"boot", CMD_BOOT},
+ {"cd", CMD_CD},
+ {"device", CMD_DEVICE},
+ {"help", CMD_HELP},
+ {"image", CMD_IMAGE},
+ {"ls", CMD_LS},
+ {"nope", CMD_NOPE},
+ {"reboot", CMD_REBOOT},
+ {"set", CMD_SET},
+ {NULL, 0},
+};
+
+extern char version[];
+void ls __P((char *, register struct stat *));
+char skipblnk __P((void));
+
+char cmd_buf[133];
+
+int
+getcmd(cmd)
+ register struct cmd_state *cmd;
+{
+ register struct cmd_table *ct = cmd_table;
+ register char *p = cmd_buf; /* input */
+ register char ch;
+ int len;
+
+ cmd->rc = 0;
+ cmd->argc = 1;
+
+ for (len = cmd->timeout; len-- && !ischar(); );
+
+ if (len < 0) {
+ cmd->cmd = CMD_BOOT;
+ cmd->argv[0] = cmd_table[CMD_BOOT].cmd_name;
+ cmd->argv[1] = NULL;
+ return 0;
+ }
+
+ ch = skipblnk();
+
+ for (len = 0; ch != '\n' &&
+ ch != ' ' && ch != '\t'; len++, ch = getchar())
+ *p++ = ch;
+ *p = '\0';
+
+ if (len == 0 && ch == '\n') {
+ cmd->cmd = CMD_NOPE;
+ return 0;
+ }
+
+ while (ct->cmd_name != NULL &&
+ strncmp(cmd_buf, ct->cmd_name, len))
+ ct++;
+
+ if (ct->cmd_name == NULL) {
+ cmd->cmd = CMD_ERROR;
+ cmd->argv[0] = ct->cmd_name;
+ return 0;
+ }
+
+ cmd->cmd = ct->cmd_id;
+ cmd->argv[0] = ct->cmd_name;
+ if (ct->cmd_name != NULL) {
+ while (ch != '\n') {
+
+ ch = skipblnk();
+
+ if (ch != '\n') {
+ cmd->argv[cmd->argc] = p;
+ *p++ = ch;
+ for (len = 0; (ch = getchar()) != '\n' &&
+ ch != ' ' && ch != '\t'; len++)
+ *p++ = ch;
+ *p++ = '\0';
+ if (len != 0)
+ cmd->argc++;
+ }
+ }
+ cmd->argv[cmd->argc] = NULL;
+ }
+
+ return cmd->rc;
+}
+
+char
+skipblnk()
+{
+ register char ch;
+
+ /* skip blanks */
+ while ((ch = getchar()) != '\n' &&
+ (ch == ' ' || ch == '\t'));
+
+ return ch;
+}
+
+int
+execmd(cmd)
+ register struct cmd_state *cmd;
+{
+ struct stat sb;
+ int fd;
+ register char *p, *q;
+ register struct cmd_table *ct;
+
+ cmd->rc = 0;
+
+ switch (cmd->cmd) {
+
+ case CMD_HELP:
+ printf("commands: ");
+ for (ct = cmd_table; ct->cmd_name != NULL; ct++)
+ printf(" %s", ct->cmd_name);
+ putchar('\n');
+ break;
+
+ case CMD_DEVICE:
+ if (cmd->argc != 2)
+ printf("device: device name required\n");
+ else {
+ strncpy(cmd->bootdev, cmd->argv[1],
+ sizeof(cmd->bootdev));
+ }
+ break;
+
+ case CMD_IMAGE:
+ if (cmd->argc != 2)
+ printf("image: pathname required\n");
+ else {
+ strncpy(cmd->image, cmd->argv[1],
+ sizeof(cmd->image));
+ }
+ break;
+
+ case CMD_ADDR:
+ if (cmd->argc != 2)
+ printf("addr: address required\n");
+ else {
+ register u_long a;
+
+ p = cmd->argv[1];
+ if (p[0] == '0' && p[1] == 'x')
+ p += 2;
+ for (a = 0; *p != '\0'; p++) {
+ a <<= 4;
+ a |= (isdigit(*p)? *p - '0':
+ 10 + tolower(*p) - 'a') & 0xf;
+ }
+
+ cmd->addr = (void *)a;
+ }
+ break;
+
+ case CMD_LS:
+ {
+ q = cmd->argv[1] == NULL? "." : cmd->argv[1];
+ sprintf(cmd->path, "%s%s%s",
+ cmd->bootdev, cmd->cwd, q);
+
+ if (stat(cmd->path, &sb) < 0) {
+ printf("stat(%s): %d\n", cmd->path, errno);
+ break;
+ }
+
+ if ((sb.st_mode & S_IFMT) != S_IFDIR)
+ ls(q, &sb);
+ else {
+ if ((fd = opendir(cmd->path)) < 0) {
+ printf ("opendir(%s): %d\n",
+ cmd->path, errno);
+ break;
+ }
+
+ p = cmd->path + strlen(cmd->path);
+ *p++ = '/';
+ *p = '\0';
+
+ while(readdir(fd, p) >= 0 && *p != '\0') {
+
+ if (stat(cmd->path, &sb) < 0) {
+ printf("stat(%s): %d\n",
+ cmd->path, errno);
+ break;
+ }
+ ls(p, &sb);
+ }
+
+ closedir (fd);
+ }
+ }
+ break;
+
+ case CMD_CD:
+ if (cmd->argc == 1) {
+ cmd->cwd[0] = '/';
+ cmd->cwd[1] = '\0';
+ break;
+ }
+
+ if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '\0')
+ break;
+
+ if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '.'
+ && cmd->argv[1][2] == '\0') {
+ /* strrchr(cmd->cwd, '/'); */
+ for (p = cmd->cwd; *++p;);
+ for (p--; *--p != '/';);
+ p[1] = '\0';
+ break;
+ }
+
+ sprintf(cmd->path, "%s%s%s",
+ cmd->bootdev, cmd->cwd, cmd->argv[1]);
+ if (stat(cmd->path, &sb) < 0) {
+ printf("stat(%s): %d\n", cmd->argv[1], errno);
+ break;
+ }
+
+ if (!S_ISDIR(sb.st_mode)) {
+ printf("boot: %s: not a dir\n", cmd->argv[1]);
+ break;
+ }
+
+ /* change dir */
+ for (p = cmd->cwd; *p; p++);
+ for (q = cmd->argv[1]; (*p++ = *q++) != '\0';);
+ if (p[-2] != '/') {
+ p[-1] = '/';
+ p[0] = '\0';
+ }
+ break;
+
+ case CMD_SET:
+ printf("OpenBSD boot version %s\n"
+ "device:\t%s\n"
+ "cwd:\t%s\n"
+ "image:\t%s\n"
+ "load at:\t%p\n"
+ "timeout:\t%d\n",
+ version, cmd->bootdev, cmd->cwd, cmd->image,
+ cmd->addr, cmd->timeout);
+ break;
+
+ case CMD_REBOOT:
+ exit(1);
+ break;
+
+ case CMD_BOOT:
+ return 1;
+ break;
+
+ case CMD_ERROR:
+ default:
+ printf ("%s: invalid command\n", cmd->argv[0]);
+ case CMD_NOPE:
+ break;
+ }
+
+ return cmd->rc;
+}
+
+#define lsrwx(mode,s) \
+ putchar ((mode) & S_IROTH? 'r' : '-'); \
+ putchar ((mode) & S_IWOTH? 'w' : '-'); \
+ putchar ((mode) & S_IXOTH? *(s): (s)[1]);
+
+void
+ls(name, sb)
+ char *name;
+ register struct stat *sb;
+{
+ putchar("-fc-d-b---l-s-w-"[(sb->st_mode & S_IFMT) >> 12]);
+ lsrwx(sb->st_mode >> 6, (sb->st_mode & S_ISUID? "sS" : "x-"));
+ lsrwx(sb->st_mode >> 3, (sb->st_mode & S_ISUID? "sS" : "x-"));
+ lsrwx(sb->st_mode , (sb->st_mode & S_ISTXT? "tT" : "x-"));
+
+ printf (" %s\tuid=%u\tgid=%u\t%lu\n", name, sb->st_uid, sb->st_gid,
+ (u_long)sb->st_size);
+}
+
diff --git a/sys/stand/boot/cmd.h b/sys/stand/boot/cmd.h
new file mode 100644
index 00000000000..35f3d58348a
--- /dev/null
+++ b/sys/stand/boot/cmd.h
@@ -0,0 +1,53 @@
+/* $OpenBSD: cmd.h,v 1.1 1997/03/31 03:12:03 weingart Exp $ */
+
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+struct cmd_state {
+ char bootdev[16]; /* device */
+ char image[32]; /* image */
+ char cwd[MAXPATHLEN - 32 - 32];
+ void *addr; /* load here */
+ int timeout;
+ char path[MAXPATHLEN]; /* buffer for pathname compose */
+
+ enum { CMD_ADDR, CMD_BOOT, CMD_CD, CMD_DEVICE, CMD_HELP,
+ CMD_IMAGE, CMD_LS, CMD_NOPE, CMD_REBOOT, CMD_SET,
+ CMD_ERROR /* last !!! */ };
+ int cmd;
+ int argc;
+ char *argv[8]; /* XXX i hope this is enough */
+ int rc;
+};
+
+int getcmd __P((register struct cmd_state *));
+int execmd __P((register struct cmd_state *));