summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorrnordier <rnordier@FreeBSD.org>1999-02-21 21:23:42 +0000
committerrnordier <rnordier@FreeBSD.org>1999-02-21 21:23:42 +0000
commit5028d48a50af15d2232b9a6c2e085834fdd6f3f9 (patch)
treed5d6ab97393e97feb7fa8ab3dd4fafa273ad461b /usr.sbin
parentc4aec13535e56f9b28426e8a4cc096dab9d9fd9e (diff)
downloadFreeBSD-src-5028d48a50af15d2232b9a6c2e085834fdd6f3f9.zip
FreeBSD-src-5028d48a50af15d2232b9a6c2e085834fdd6f3f9.tar.gz
Add boot0cfg: this installs/configures the `boot0' boot manager. A
CLI utility to do this has been requested by a few people.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/boot0cfg/Makefile6
-rw-r--r--usr.sbin/boot0cfg/boot0cfg.8137
-rw-r--r--usr.sbin/boot0cfg/boot0cfg.c267
3 files changed, 410 insertions, 0 deletions
diff --git a/usr.sbin/boot0cfg/Makefile b/usr.sbin/boot0cfg/Makefile
new file mode 100644
index 0000000..6f965e3
--- /dev/null
+++ b/usr.sbin/boot0cfg/Makefile
@@ -0,0 +1,6 @@
+# $Id: $
+
+PROG= boot0cfg
+MAN8= boot0cfg.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/boot0cfg/boot0cfg.8 b/usr.sbin/boot0cfg/boot0cfg.8
new file mode 100644
index 0000000..28a5d9e
--- /dev/null
+++ b/usr.sbin/boot0cfg/boot0cfg.8
@@ -0,0 +1,137 @@
+.\" Copyright (c) 1999 Robert Nordier
+.\" 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.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``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 AUTHOR 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.
+.\"
+.\" $Id: $
+.\"
+.Dd February 21, 1999
+.Dt BOOT0CFG 8
+.Os
+.Sh NAME
+.Nm boot0cfg
+.Nd boot manager installation/configuration utility
+.Sh SYNOPSIS
+.Nm boot0cfg
+.Op Fl Bv
+.Op Fl b Ar boot0
+.Op Fl d Ar drive
+.Op Fl f Ar file
+.Op Fl o Ar options
+.Op Fl t Ar ticks
+.Ar disk
+.Sh DESCRIPTION
+The FreeBSD
+.Sq boot0
+boot manager permits the operator to select from which disk and which
+slice an i386 machine (PC) is booted.
+.Pp
+Note that what are referred to here as
+.Dq slices
+are typically called
+.Dq partitions
+in non-BSD documentation relating to the PC. Typically, only
+non-removable disks are sliced.
+.Pp
+The
+.Nm
+utility optionally installs the
+.Sq boot0
+boot manager on the specified
+.Ar disk ;
+and allows various operational parameters to be configured.
+.Pp
+On PCs, a boot manager typically occupies sector 0 of a disk, which is
+known as the Master Boot Record (MBR). The MBR contains both code (to
+which control is passed by the PC BIOS) and data (an embedded table of
+defined slices).
+.Pp
+The options are:
+.Bl -tag -width indent
+.It Fl B
+Install the
+.Sq boot0
+boot manager. This option causes MBR code to be replaced, but without
+affecting the embedded slice table.
+.It Fl v
+Verbose: display information about the slices defined, etc.
+.It Fl b Ar boot0
+Specify which
+.Sq boot0
+image to use. The default is /boot/boot0.
+.It Fl d Ar drive
+Specify the drive number used by the PC BIOS in referencing the drive
+which contains the specified
+.Ar disk .
+Typically this will be 0x80 for the first hard drive, 0x81 for the
+second hard drive, and so on; however any integer between 0 and 0xff
+is acceptable here.
+.It Fl f Ar file
+Specify that a backup copy of the preexisting MBR should be written to
+.Ar file .
+This file is created if it does not exist, and truncated if it does.
+.It Fl o Ar options
+A comma-separated string of any of the following options may be
+specified (with
+.Dq no
+prepended as necessary):
+.Bl -tag -width indent
+.It packet
+Use the disk packet (BIOS Int 0x13 extensions) interface rather than
+the conventional (CHS) interface, when accessing disk-related BIOS
+services. The default is
+.Sq nopacket .
+.It setdrv
+Causes the drive containing the disk to be referenced using drive
+number definable by means of the -d option. The default is
+.Sq nosetdrv .
+.It update
+Allow the MBR to be updated by the boot manager. (The MBR may be
+updated to flag slices as
+.Sq active ,
+and to save slice selection information.) This is the default; a
+.Sq noupdate
+option causes the MBR to be treated as read-only.
+.El
+.It Fl t Ar secs
+Set the timeout value to
+.Ar ticks .
+(There are approximately 18.2 ticks per second.)
+.El
+.Sh SEE ALSO
+.Xr boot 8 ,
+.Xr fdisk 8 .
+.Sh DIAGNOSTICS
+Exit status is 0 on success and >0 on error.
+.Sh AUTHORS
+.An Robert Nordier Aq rnordier@FreeBSD.org .
+.Sh BUGS
+Use of the
+.Sq packet
+option may cause
+.Sq boot0
+to fail, depending on the nature of BIOS support.
+.Pp
+The
+.Sq setdrv
+option is presently implemented
+.Dq syntactically but not semantically .
diff --git a/usr.sbin/boot0cfg/boot0cfg.c b/usr.sbin/boot0cfg/boot0cfg.c
new file mode 100644
index 0000000..4075023
--- /dev/null
+++ b/usr.sbin/boot0cfg/boot0cfg.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 1999 Robert Nordier
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``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 AUTHOR 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.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+"$Id: $";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define MBRSIZE 512 /* master boot record size */
+
+#define OFF_FLAGS 0x1bb /* offset: option flags */
+#define OFF_TICKS 0x1bc /* offset: clock ticks */
+#define OFF_PTBL 0x1be /* offset: partition table */
+#define OFF_MAGIC 0x1fe /* offset: magic number */
+
+#define cv2(p) ((p)[0] | (p)[1] << 010)
+
+#define mk2(p, x) \
+ (p)[0] = (u_int8_t)(x), \
+ (p)[1] = (u_int8_t)((x) >> 010)
+
+static const struct {
+ const char *tok;
+ int def;
+} opttbl[] = {
+ {"packet", 0},
+ {"update", 1},
+ {"setdrv", 0}
+};
+static const int nopt = sizeof(opttbl) / sizeof(opttbl[0]);
+
+static const char fmt0[] = "# flag start chs type"
+ " end chs offset size\n";
+
+static const char fmt1[] = "%d 0x%02x %4u:%3u:%2u 0x%02x"
+ " %4u:%3u:%2u %10u %10u\n";
+
+static void stropt(const char *, int *, int *);
+static char *mkrdev(const char *);
+static int argtoi(const char *, int, int, int);
+static void usage(void);
+
+int
+main(int argc, char *argv[])
+{
+ u_int8_t buf[MBRSIZE];
+ struct dos_partition part[4];
+ const char *bpath, *fpath, *disk;
+ ssize_t n;
+ int B_flag, v_flag, o_flag;
+ int d_arg, t_arg;
+ int o_and, o_or;
+ int fd, fd1, up, c, i;
+
+ bpath = "/boot/boot0";
+ fpath = NULL;
+ B_flag = v_flag = o_flag = 0;
+ d_arg = t_arg = -1;
+ o_and = 0xff;
+ o_or = 0;
+ while ((c = getopt(argc, argv, "Bvb:d:f:o:t:")) != -1)
+ switch (c) {
+ case 'B':
+ B_flag = 1;
+ break;
+ case 'v':
+ v_flag = 1;
+ break;
+ case 'b':
+ bpath = optarg;
+ break;
+ case 'd':
+ d_arg = argtoi(optarg, 0, 0xff, 'd');
+ break;
+ case 'f':
+ fpath = optarg;
+ break;
+ case 'o':
+ stropt(optarg, &o_and, &o_or);
+ o_flag = 1;
+ break;
+ case 't':
+ t_arg = argtoi(optarg, 1, 0xffff, 't');
+ break;
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc != 1)
+ usage();
+ disk = mkrdev(*argv);
+ up = B_flag || d_arg || o_flag || t_arg;
+ if ((fd = open(disk, up ? O_RDWR : O_RDONLY)) == -1)
+ err(1, "%s", disk);
+ if ((n = read(fd, buf, MBRSIZE)) == -1)
+ err(1, "%s", disk);
+ if (n != MBRSIZE)
+ errx(1, "%s: short read", disk);
+ if (cv2(buf + OFF_MAGIC) != 0xaa55)
+ errx(1, "%s: bad magic", disk);
+ if (fpath) {
+ if ((fd1 = open(fpath, O_WRONLY | O_CREAT | O_TRUNC,
+ 0666)) == -1 ||
+ (n = write(fd1, buf, MBRSIZE)) == -1 || close(fd1))
+ err(1, "%s", fpath);
+ if (n != MBRSIZE)
+ errx(1, "%s: short write", fpath);
+ }
+ memcpy(part, buf + OFF_PTBL, sizeof(part));
+ if (B_flag) {
+ if ((fd1 = open(bpath, O_RDONLY)) == -1 ||
+ (n = read(fd1, buf, MBRSIZE)) == -1 || close(fd1))
+ err(1, "%s", bpath);
+ if (n != MBRSIZE)
+ errx(1, "%s: short read", bpath);
+ if (cv2(buf + OFF_MAGIC) != 0xaa55)
+ errx(1, "%s: bad magic", bpath);
+ memcpy(buf + OFF_PTBL, part, sizeof(part));
+ }
+ if (o_flag) {
+ buf[OFF_FLAGS] &= o_and;
+ buf[OFF_FLAGS] |= o_or;
+ }
+ if (t_arg != -1)
+ mk2(buf + OFF_TICKS, t_arg);
+ if (up) {
+ if (lseek(fd, 0, SEEK_SET) == -1 ||
+ (n = write(fd, buf, MBRSIZE)) == -1 || close(fd))
+ err(1, "%s", disk);
+ if (n != MBRSIZE)
+ errx(1, "%s: short write", disk);
+ }
+ if (v_flag) {
+ printf(fmt0);
+ for (i = 0; i < 4; i++)
+ if (part[i].dp_typ) {
+ printf(fmt1,
+ 1 + i,
+ part[i].dp_flag,
+ part[i].dp_scyl + ((part[i].dp_ssect & 0xc0) << 2),
+ part[i].dp_shd,
+ part[i].dp_ssect & 0x3f,
+ part[i].dp_typ,
+ part[i].dp_ecyl + ((part[i].dp_esect & 0xc0) << 2),
+ part[i].dp_ehd,
+ part[i].dp_esect & 0x3f,
+ part[i].dp_start,
+ part[i].dp_size);
+ }
+ printf("\n");
+ printf("drive=0x0 options=");
+ for (i = 0; i < nopt; i++) {
+ if (i)
+ printf(",");
+ if (!(buf[OFF_FLAGS] & 1 << (7 - i)) ^ opttbl[i].def)
+ printf("no");
+ printf("%s", opttbl[i].tok);
+ }
+ printf(" ticks=%u\n", cv2(buf + OFF_TICKS));
+ }
+ return 0;
+}
+
+static void
+stropt(const char *arg, int *xa, int *xo)
+{
+ const char *q;
+ char *s, *s1;
+ int inv, i, x;
+
+ if (!(s = strdup(arg)))
+ err(1, NULL);
+ for (s1 = s; (q = strtok(s1, ",")); s1 = NULL) {
+ if ((inv = !strncmp(q, "no", 2)))
+ q += 2;
+ for (i = 0; i < nopt; i++)
+ if (!strcmp(q, opttbl[i].tok))
+ break;
+ if (i == nopt)
+ errx(1, "%s: Unknown -o option", q);
+ if (opttbl[i].def)
+ inv ^= 1;
+ x = 1 << (7 - i);
+ if (inv)
+ *xa &= ~x;
+ else
+ *xo |= x;
+ }
+ free(s);
+}
+
+static char *
+mkrdev(const char *fname)
+{
+ char buf[MAXPATHLEN];
+ struct stat sb;
+ char *s;
+
+ s = (char *) fname;
+ if (!strchr(fname, '/')) {
+ snprintf(buf, sizeof(buf), "%sr%s", _PATH_DEV, fname);
+ if (stat(buf, &sb))
+ snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname);
+ if (!(s = strdup(buf)))
+ err(1, NULL);
+ }
+ return s;
+}
+
+static int
+argtoi(const char *arg, int lo, int hi, int opt)
+{
+ char *s;
+ long x;
+
+ errno = 0;
+ x = strtol(arg, &s, 0);
+ if (errno || !*arg || *s || x < lo || x > hi)
+ errx(1, "%s: Bad argument to -%c option", arg, opt);
+ return x;
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "%s\n%s\n",
+ "usage: boot0cfg [-Bv] [-b boot0] [-d drive] [-f file] [-o options]",
+ " [-t ticks] disk");
+ exit(1);
+}
OpenPOWER on IntegriCloud