summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2020-06-27 15:35:30 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2020-06-27 15:35:30 +0000
commit2a4e82f6774eaf7ee452093cb4d4a049687e95d8 (patch)
tree54e5ad586592efca7dfa7132967a5f21a9cba5af /usr.sbin
parent88aa1dbacd2d4a01b00a325be1b0bf2862d7ecad (diff)
convert macppc, octeon, and loongson to use MI installboot, removing
special case scripting in install.md. (macppc still requires manual steps for HFS bootmode) tested by krw, visa, gkoehler
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/installboot/Makefile8
-rw-r--r--usr.sbin/installboot/armv7_installboot.c8
-rw-r--r--usr.sbin/installboot/i386_installboot.c6
-rw-r--r--usr.sbin/installboot/i386_installboot.h4
-rw-r--r--usr.sbin/installboot/i386_softraid.c4
-rw-r--r--usr.sbin/installboot/loongson_installboot.c254
-rw-r--r--usr.sbin/installboot/macppc_installboot.c244
-rw-r--r--usr.sbin/installboot/octeon_installboot.c244
8 files changed, 760 insertions, 12 deletions
diff --git a/usr.sbin/installboot/Makefile b/usr.sbin/installboot/Makefile
index a88d84e8b4e..1938d3bd5e6 100644
--- a/usr.sbin/installboot/Makefile
+++ b/usr.sbin/installboot/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.20 2017/05/07 10:40:17 kettenis Exp $
+# $OpenBSD: Makefile,v 1.21 2020/06/27 15:35:29 deraadt Exp $
PROG= installboot
SRCS= installboot.c util.c
@@ -23,6 +23,12 @@ SRCS += hppa_installboot.c
.elif ${MACHINE} == "landisk"
CFLAGS += -DBOOTSTRAP
SRCS += landisk_installboot.c
+.elif ${MACHINE} == "loongson"
+SRCS += loongson_installboot.c
+.elif ${MACHINE} == "macppc"
+SRCS += macppc_installboot.c
+.elif ${MACHINE} == "octeon"
+SRCS += octeon_installboot.c
.elif ${MACHINE} == "sparc64"
CFLAGS += -DSOFTRAID
SRCS += sparc64_installboot.c
diff --git a/usr.sbin/installboot/armv7_installboot.c b/usr.sbin/installboot/armv7_installboot.c
index 5e16f436605..809d4e67016 100644
--- a/usr.sbin/installboot/armv7_installboot.c
+++ b/usr.sbin/installboot/armv7_installboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: armv7_installboot.c,v 1.4 2019/06/28 13:32:48 deraadt Exp $ */
+/* $OpenBSD: armv7_installboot.c,v 1.5 2020/06/27 15:35:29 deraadt Exp $ */
/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
/*
@@ -53,7 +53,7 @@
#include "installboot.h"
-static void write_efisystem(struct disklabel *, char);
+static void write_filesystem(struct disklabel *, char);
static int findmbrfat(int, struct disklabel *);
void
@@ -84,14 +84,14 @@ md_installboot(int devfd, char *dev)
part = findmbrfat(devfd, &dl);
if (part != -1) {
- write_efisystem(&dl, (char)part);
+ write_filesystem(&dl, (char)part);
return;
}
}
static void
-write_efisystem(struct disklabel *dl, char part)
+write_filesystem(struct disklabel *dl, char part)
{
static char *fsckfmt = "/sbin/fsck_msdos %s >/dev/null";
static char *newfsfmt ="/sbin/newfs_msdos %s >/dev/null";
diff --git a/usr.sbin/installboot/i386_installboot.c b/usr.sbin/installboot/i386_installboot.c
index a904ed981c1..32ff6765e30 100644
--- a/usr.sbin/installboot/i386_installboot.c
+++ b/usr.sbin/installboot/i386_installboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i386_installboot.c,v 1.36 2020/03/09 06:16:56 otto Exp $ */
+/* $OpenBSD: i386_installboot.c,v 1.37 2020/06/27 15:35:29 deraadt Exp $ */
/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
/*
@@ -146,7 +146,7 @@ md_installboot(int devfd, char *dev)
part = findgptefisys(devfd, &dl);
if (part != -1) {
- write_efisystem(&dl, (char)part);
+ write_filesystem(&dl, (char)part);
return;
}
@@ -222,7 +222,7 @@ write_bootblocks(int devfd, char *dev, struct disklabel *dl)
}
void
-write_efisystem(struct disklabel *dl, char part)
+write_filesystem(struct disklabel *dl, char part)
{
static char *fsckfmt = "/sbin/fsck_msdos %s >/dev/null";
static char *newfsfmt ="/sbin/newfs_msdos %s >/dev/null";
diff --git a/usr.sbin/installboot/i386_installboot.h b/usr.sbin/installboot/i386_installboot.h
index 407c61eeaee..0f75c057d06 100644
--- a/usr.sbin/installboot/i386_installboot.h
+++ b/usr.sbin/installboot/i386_installboot.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: i386_installboot.h,v 1.5 2019/09/02 16:36:12 otto Exp $ */
+/* $OpenBSD: i386_installboot.h,v 1.6 2020/06/27 15:35:29 deraadt Exp $ */
/*
* Copyright (c) 2011 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2003 Tom Cosgrove <tom.cosgrove@arches-consulting.com>
@@ -55,4 +55,4 @@ void pbr_set_symbols(char *, char *, struct sym_data *);
void sym_set_value(struct sym_data *, char *, u_int32_t);
void write_bootblocks(int, char *, struct disklabel *);
int findgptefisys(int, struct disklabel *);
-void write_efisystem(struct disklabel *, char);
+void write_filesystem(struct disklabel *, char);
diff --git a/usr.sbin/installboot/i386_softraid.c b/usr.sbin/installboot/i386_softraid.c
index 9971a23496d..a271d9c61da 100644
--- a/usr.sbin/installboot/i386_softraid.c
+++ b/usr.sbin/installboot/i386_softraid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i386_softraid.c,v 1.16 2020/06/08 19:17:12 kn Exp $ */
+/* $OpenBSD: i386_softraid.c,v 1.17 2020/06/27 15:35:29 deraadt Exp $ */
/*
* Copyright (c) 2012 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2010 Otto Moerbeek <otto@drijf.net>
@@ -89,7 +89,7 @@ sr_install_bootblk(int devfd, int vol, int disk)
efipart = findgptefisys(diskfd, &dl);
if (efipart != -1) {
- write_efisystem(&dl, (char)efipart);
+ write_filesystem(&dl, (char)efipart);
return;
}
diff --git a/usr.sbin/installboot/loongson_installboot.c b/usr.sbin/installboot/loongson_installboot.c
new file mode 100644
index 00000000000..f729ffbbf1c
--- /dev/null
+++ b/usr.sbin/installboot/loongson_installboot.c
@@ -0,0 +1,254 @@
+/* $OpenBSD: loongson_installboot.c,v 1.1 2020/06/27 15:35:29 deraadt Exp $ */
+/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
+
+/*
+ * Copyright (c) 2011 Joel Sing <jsing@openbsd.org>
+ * Copyright (c) 2010 Otto Moerbeek <otto@openbsd.org>
+ * Copyright (c) 2003 Tom Cosgrove <tom.cosgrove@arches-consulting.com>
+ * Copyright (c) 1997 Michael Shalayeff
+ * Copyright (c) 1994 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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 AUTHOR 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> /* DEV_BSIZE */
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+
+#include "installboot.h"
+
+static void write_filesystem(struct disklabel *, char);
+static int findmbrfat(int, struct disklabel *);
+
+void
+md_init(void)
+{
+}
+
+void
+md_loadboot(void)
+{
+}
+
+void
+md_installboot(int devfd, char *dev)
+{
+ struct disklabel dl;
+ int part;
+
+ /* Get and check disklabel. */
+ if (ioctl(devfd, DIOCGDINFO, &dl) == -1)
+ err(1, "disklabel: %s", dev);
+ if (dl.d_magic != DISKMAGIC)
+ errx(1, "bad disklabel magic=0x%08x", dl.d_magic);
+
+ /* Warn on unknown disklabel types. */
+ if (dl.d_type == 0)
+ warnx("disklabel type unknown");
+
+ part = findmbrfat(devfd, &dl);
+ if (part != -1) {
+ write_filesystem(&dl, (char)part);
+ return;
+ }
+}
+
+
+static void
+write_filesystem(struct disklabel *dl, char part)
+{
+ static char *fsckfmt = "/sbin/fsck_ext2fs %s >/dev/null";
+ static char *newfsfmt ="/sbin/newfs_ext2fs %s >/dev/null";
+ struct ufs_args args;
+ char cmd[60];
+ char dst[PATH_MAX];
+ char *src;
+ size_t mntlen, pathlen, srclen;
+ int rslt;
+
+ src = NULL;
+
+ /* Create directory for temporary mount point. */
+ strlcpy(dst, "/tmp/installboot.XXXXXXXXXX", sizeof(dst));
+ if (mkdtemp(dst) == NULL)
+ err(1, "mkdtemp('%s') failed", dst);
+ mntlen = strlen(dst);
+
+ /* Mount <duid>.<part> as ext2fs filesystem. */
+ memset(&args, 0, sizeof(args));
+ rslt = asprintf(&args.fspec,
+ "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx.%c",
+ dl->d_uid[0], dl->d_uid[1], dl->d_uid[2], dl->d_uid[3],
+ dl->d_uid[4], dl->d_uid[5], dl->d_uid[6], dl->d_uid[7],
+ part);
+ if (rslt == -1) {
+ warn("bad special device");
+ goto rmdir;
+ }
+
+ args.export_info.ex_root = -2;
+ args.export_info.ex_flags = 0;
+
+ if (mount(MOUNT_EXT2FS, dst, 0, &args) == -1) {
+ /* Try fsck'ing it. */
+ rslt = snprintf(cmd, sizeof(cmd), fsckfmt, args.fspec);
+ if (rslt >= sizeof(cmd)) {
+ warnx("can't build fsck command");
+ rslt = -1;
+ goto rmdir;
+ }
+ rslt = system(cmd);
+ if (rslt == -1) {
+ warn("system('%s') failed", cmd);
+ goto rmdir;
+ }
+ if (mount(MOUNT_EXT2FS, dst, 0, &args) == -1) {
+ /* Try newfs'ing it. */
+ rslt = snprintf(cmd, sizeof(cmd), newfsfmt,
+ args.fspec);
+ if (rslt >= sizeof(cmd)) {
+ warnx("can't build newfs command");
+ rslt = -1;
+ goto rmdir;
+ }
+ rslt = system(cmd);
+ if (rslt == -1) {
+ warn("system('%s') failed", cmd);
+ goto rmdir;
+ }
+ rslt = mount(MOUNT_EXT2FS, dst, 0, &args);
+ if (rslt == -1) {
+ warn("unable to mount EFI System partition");
+ goto rmdir;
+ }
+ }
+ }
+
+ /* Create "/boot" directory in <duid>.<part>. */
+ if (strlcat(dst, "/boot", sizeof(dst)) >= sizeof(dst)) {
+ rslt = -1;
+ warn("unable to build /efi directory");
+ goto umount;
+ }
+ rslt = mkdir(dst, 0755);
+ if (rslt == -1 && errno != EEXIST) {
+ warn("mkdir('%s') failed", dst);
+ goto umount;
+ }
+
+ /*
+ * Copy /usr/mdec/boot to /boot/boot.
+ */
+ pathlen = strlen(dst);
+ if (strlcat(dst, "/boot", sizeof(dst)) >= sizeof(dst)) {
+ rslt = -1;
+ warn("unable to build /boot path");
+ goto umount;
+ }
+ src = fileprefix(root, "/usr/mdec/boot");
+ if (src == NULL) {
+ rslt = -1;
+ goto umount;
+ }
+ srclen = strlen(src);
+ if (verbose)
+ fprintf(stderr, "%s %s to %s\n",
+ (nowrite ? "would copy" : "copying"), src, dst);
+ if (!nowrite) {
+ rslt = filecopy(src, dst);
+ if (rslt == -1)
+ goto umount;
+ }
+
+ rslt = 0;
+
+umount:
+ dst[mntlen] = '\0';
+ if (unmount(dst, MNT_FORCE) == -1)
+ err(1, "unmount('%s') failed", dst);
+
+rmdir:
+ free(args.fspec);
+ dst[mntlen] = '\0';
+ if (rmdir(dst) == -1)
+ err(1, "rmdir('%s') failed", dst);
+
+ free(src);
+
+ if (rslt == -1)
+ exit(1);
+}
+
+int
+findmbrfat(int devfd, struct disklabel *dl)
+{
+ struct dos_partition dp[NDOSPART];
+ ssize_t len;
+ u_int64_t start = 0;
+ int i;
+ u_int8_t *secbuf;
+
+ if ((secbuf = malloc(dl->d_secsize)) == NULL)
+ err(1, NULL);
+
+ /* Read MBR. */
+ len = pread(devfd, secbuf, dl->d_secsize, 0);
+ if (len != dl->d_secsize)
+ err(4, "can't read mbr");
+ memcpy(dp, &secbuf[DOSPARTOFF], sizeof(dp));
+
+ for (i = 0; i < NDOSPART; i++) {
+ if (dp[i].dp_typ == DOSPTYP_UNUSED)
+ continue;
+ if (dp[i].dp_typ == DOSPTYP_LINUX)
+ start = dp[i].dp_start;
+ }
+
+ free(secbuf);
+
+ if (start) {
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ if (DL_GETPSIZE(&dl->d_partitions[i]) > 0 &&
+ DL_GETPOFFSET(&dl->d_partitions[i]) == start)
+ return ('a' + i);
+ }
+ }
+
+ return (-1);
+}
diff --git a/usr.sbin/installboot/macppc_installboot.c b/usr.sbin/installboot/macppc_installboot.c
new file mode 100644
index 00000000000..80e59548421
--- /dev/null
+++ b/usr.sbin/installboot/macppc_installboot.c
@@ -0,0 +1,244 @@
+/* $OpenBSD: macppc_installboot.c,v 1.1 2020/06/27 15:35:29 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2011 Joel Sing <jsing@openbsd.org>
+ * Copyright (c) 2010 Otto Moerbeek <otto@openbsd.org>
+ * Copyright (c) 2003 Tom Cosgrove <tom.cosgrove@arches-consulting.com>
+ * Copyright (c) 1997 Michael Shalayeff
+ * Copyright (c) 1994 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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 AUTHOR 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> /* DEV_BSIZE */
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+#include <endian.h>
+
+#include "installboot.h"
+
+static void write_filesystem(struct disklabel *, char);
+static int findmbrfat(int, struct disklabel *);
+
+void
+md_init(void)
+{
+}
+
+void
+md_loadboot(void)
+{
+}
+
+void
+md_installboot(int devfd, char *dev)
+{
+ struct disklabel dl;
+ int part;
+
+ /* Get and check disklabel. */
+ if (ioctl(devfd, DIOCGDINFO, &dl) == -1)
+ err(1, "disklabel: %s", dev);
+ if (dl.d_magic != DISKMAGIC)
+ errx(1, "bad disklabel magic=0x%08x", dl.d_magic);
+
+ /* Warn on unknown disklabel types. */
+ if (dl.d_type == 0)
+ warnx("disklabel type unknown");
+
+ part = findmbrfat(devfd, &dl);
+ if (part != -1) {
+ write_filesystem(&dl, (char)part);
+ return;
+ }
+}
+
+
+static void
+write_filesystem(struct disklabel *dl, char part)
+{
+ static char *fsckfmt = "/sbin/fsck_msdos %s >/dev/null";
+ static char *newfsfmt ="/sbin/newfs_msdos %s >/dev/null";
+ struct ufs_args args;
+ char cmd[60];
+ char dst[PATH_MAX];
+ char *src;
+ size_t mntlen, pathlen, srclen;
+ int rslt;
+
+ src = NULL;
+
+ /* Create directory for temporary mount point. */
+ strlcpy(dst, "/tmp/installboot.XXXXXXXXXX", sizeof(dst));
+ if (mkdtemp(dst) == NULL)
+ err(1, "mkdtemp('%s') failed", dst);
+ mntlen = strlen(dst);
+
+ /* Mount <duid>.<part> as msdos filesystem. */
+ memset(&args, 0, sizeof(args));
+ rslt = asprintf(&args.fspec,
+ "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx.%c",
+ dl->d_uid[0], dl->d_uid[1], dl->d_uid[2], dl->d_uid[3],
+ dl->d_uid[4], dl->d_uid[5], dl->d_uid[6], dl->d_uid[7],
+ part);
+ if (rslt == -1) {
+ warn("bad special device");
+ goto rmdir;
+ }
+
+ args.export_info.ex_root = -2;
+ args.export_info.ex_flags = 0;
+
+ if (mount(MOUNT_MSDOS, dst, 0, &args) == -1) {
+ /* Try fsck'ing it. */
+ rslt = snprintf(cmd, sizeof(cmd), fsckfmt, args.fspec);
+ if (rslt >= sizeof(cmd)) {
+ warnx("can't build fsck command");
+ rslt = -1;
+ goto rmdir;
+ }
+ rslt = system(cmd);
+ if (rslt == -1) {
+ warn("system('%s') failed", cmd);
+ goto rmdir;
+ }
+ if (mount(MOUNT_MSDOS, dst, 0, &args) == -1) {
+ /* Try newfs'ing it. */
+ rslt = snprintf(cmd, sizeof(cmd), newfsfmt,
+ args.fspec);
+ if (rslt >= sizeof(cmd)) {
+ warnx("can't build newfs command");
+ rslt = -1;
+ goto rmdir;
+ }
+ rslt = system(cmd);
+ if (rslt == -1) {
+ warn("system('%s') failed", cmd);
+ goto rmdir;
+ }
+ rslt = mount(MOUNT_MSDOS, dst, 0, &args);
+ if (rslt == -1) {
+ warn("unable to mount MSDOS partition");
+ goto rmdir;
+ }
+ }
+ }
+
+ /*
+ * Copy /usr/mdec/ofwboot to $FS/ofwboot.
+ */
+ pathlen = strlen(dst);
+ if (strlcat(dst, "/ofwboot", sizeof(dst)) >= sizeof(dst)) {
+ rslt = -1;
+ warn("unable to build /ofwboot path");
+ goto umount;
+ }
+ src = fileprefix(root, "/usr/mdec/ofwboot");
+ if (src == NULL) {
+ rslt = -1;
+ goto umount;
+ }
+ srclen = strlen(src);
+ if (verbose)
+ fprintf(stderr, "%s %s to %s\n",
+ (nowrite ? "would copy" : "copying"), src, dst);
+ if (!nowrite) {
+ rslt = filecopy(src, dst);
+ if (rslt == -1)
+ goto umount;
+ }
+
+ rslt = 0;
+
+umount:
+ dst[mntlen] = '\0';
+ if (unmount(dst, MNT_FORCE) == -1)
+ err(1, "unmount('%s') failed", dst);
+
+rmdir:
+ free(args.fspec);
+ dst[mntlen] = '\0';
+ if (rmdir(dst) == -1)
+ err(1, "rmdir('%s') failed", dst);
+
+ free(src);
+
+ if (rslt == -1)
+ exit(1);
+}
+
+int
+findmbrfat(int devfd, struct disklabel *dl)
+{
+ struct dos_partition dp[NDOSPART];
+ ssize_t len;
+ u_int64_t start = 0;
+ int i;
+ u_int8_t *secbuf;
+
+ if ((secbuf = malloc(dl->d_secsize)) == NULL)
+ err(1, NULL);
+
+ /* Read MBR. */
+ len = pread(devfd, secbuf, dl->d_secsize, 0);
+ if (len != dl->d_secsize)
+ err(4, "can't read mbr");
+ memcpy(dp, &secbuf[DOSPARTOFF], sizeof(dp));
+
+ for (i = 0; i < NDOSPART; i++) {
+ if (dp[i].dp_typ == DOSPTYP_UNUSED)
+ continue;
+ if (dp[i].dp_typ == DOSPTYP_FAT16L ||
+ dp[i].dp_typ == DOSPTYP_FAT32L ||
+ dp[i].dp_typ == DOSPTYP_FAT16B)
+ start = letoh32(dp[i].dp_start);
+ }
+
+ free(secbuf);
+
+ if (start) {
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ if (DL_GETPSIZE(&dl->d_partitions[i]) > 0 &&
+ DL_GETPOFFSET(&dl->d_partitions[i]) == start)
+ return ('a' + i);
+ }
+ }
+
+ return (-1);
+}
diff --git a/usr.sbin/installboot/octeon_installboot.c b/usr.sbin/installboot/octeon_installboot.c
new file mode 100644
index 00000000000..91e52159956
--- /dev/null
+++ b/usr.sbin/installboot/octeon_installboot.c
@@ -0,0 +1,244 @@
+/* $OpenBSD: octeon_installboot.c,v 1.1 2020/06/27 15:35:29 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2011 Joel Sing <jsing@openbsd.org>
+ * Copyright (c) 2010 Otto Moerbeek <otto@openbsd.org>
+ * Copyright (c) 2003 Tom Cosgrove <tom.cosgrove@arches-consulting.com>
+ * Copyright (c) 1997 Michael Shalayeff
+ * Copyright (c) 1994 Paul Kranenburg
+ * 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 Paul Kranenburg.
+ * 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 AUTHOR 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> /* DEV_BSIZE */
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+#include <endian.h>
+
+#include "installboot.h"
+
+static void write_filesystem(struct disklabel *, char);
+static int findmbrfat(int, struct disklabel *);
+
+void
+md_init(void)
+{
+}
+
+void
+md_loadboot(void)
+{
+}
+
+void
+md_installboot(int devfd, char *dev)
+{
+ struct disklabel dl;
+ int part;
+
+ /* Get and check disklabel. */
+ if (ioctl(devfd, DIOCGDINFO, &dl) == -1)
+ err(1, "disklabel: %s", dev);
+ if (dl.d_magic != DISKMAGIC)
+ errx(1, "bad disklabel magic=0x%08x", dl.d_magic);
+
+ /* Warn on unknown disklabel types. */
+ if (dl.d_type == 0)
+ warnx("disklabel type unknown");
+
+ part = findmbrfat(devfd, &dl);
+ if (part != -1) {
+ write_filesystem(&dl, (char)part);
+ return;
+ }
+}
+
+
+static void
+write_filesystem(struct disklabel *dl, char part)
+{
+ static char *fsckfmt = "/sbin/fsck_msdos %s >/dev/null";
+ static char *newfsfmt ="/sbin/newfs_msdos %s >/dev/null";
+ struct ufs_args args;
+ char cmd[60];
+ char dst[PATH_MAX];
+ char *src;
+ size_t mntlen, pathlen, srclen;
+ int rslt;
+
+ src = NULL;
+
+ /* Create directory for temporary mount point. */
+ strlcpy(dst, "/tmp/installboot.XXXXXXXXXX", sizeof(dst));
+ if (mkdtemp(dst) == NULL)
+ err(1, "mkdtemp('%s') failed", dst);
+ mntlen = strlen(dst);
+
+ /* Mount <duid>.<part> as msdos filesystem. */
+ memset(&args, 0, sizeof(args));
+ rslt = asprintf(&args.fspec,
+ "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx.%c",
+ dl->d_uid[0], dl->d_uid[1], dl->d_uid[2], dl->d_uid[3],
+ dl->d_uid[4], dl->d_uid[5], dl->d_uid[6], dl->d_uid[7],
+ part);
+ if (rslt == -1) {
+ warn("bad special device");
+ goto rmdir;
+ }
+
+ args.export_info.ex_root = -2;
+ args.export_info.ex_flags = 0;
+
+ if (mount(MOUNT_MSDOS, dst, 0, &args) == -1) {
+ /* Try fsck'ing it. */
+ rslt = snprintf(cmd, sizeof(cmd), fsckfmt, args.fspec);
+ if (rslt >= sizeof(cmd)) {
+ warnx("can't build fsck command");
+ rslt = -1;
+ goto rmdir;
+ }
+ rslt = system(cmd);
+ if (rslt == -1) {
+ warn("system('%s') failed", cmd);
+ goto rmdir;
+ }
+ if (mount(MOUNT_MSDOS, dst, 0, &args) == -1) {
+ /* Try newfs'ing it. */
+ rslt = snprintf(cmd, sizeof(cmd), newfsfmt,
+ args.fspec);
+ if (rslt >= sizeof(cmd)) {
+ warnx("can't build newfs command");
+ rslt = -1;
+ goto rmdir;
+ }
+ rslt = system(cmd);
+ if (rslt == -1) {
+ warn("system('%s') failed", cmd);
+ goto rmdir;
+ }
+ rslt = mount(MOUNT_MSDOS, dst, 0, &args);
+ if (rslt == -1) {
+ warn("unable to mount MSDOS partition");
+ goto rmdir;
+ }
+ }
+ }
+
+ /*
+ * Copy /usr/mdec/boot to /mnt/boot.
+ */
+ pathlen = strlen(dst);
+ if (strlcat(dst, "/boot", sizeof(dst)) >= sizeof(dst)) {
+ rslt = -1;
+ warn("unable to build /boot path");
+ goto umount;
+ }
+ src = fileprefix(root, "/usr/mdec/boot");
+ if (src == NULL) {
+ rslt = -1;
+ goto umount;
+ }
+ srclen = strlen(src);
+ if (verbose)
+ fprintf(stderr, "%s %s to %s\n",
+ (nowrite ? "would copy" : "copying"), src, dst);
+ if (!nowrite) {
+ rslt = filecopy(src, dst);
+ if (rslt == -1)
+ goto umount;
+ }
+
+ rslt = 0;
+
+umount:
+ dst[mntlen] = '\0';
+ if (unmount(dst, MNT_FORCE) == -1)
+ err(1, "unmount('%s') failed", dst);
+
+rmdir:
+ free(args.fspec);
+ dst[mntlen] = '\0';
+ if (rmdir(dst) == -1)
+ err(1, "rmdir('%s') failed", dst);
+
+ free(src);
+
+ if (rslt == -1)
+ exit(1);
+}
+
+int
+findmbrfat(int devfd, struct disklabel *dl)
+{
+ struct dos_partition dp[NDOSPART];
+ ssize_t len;
+ u_int64_t start = 0;
+ int i;
+ u_int8_t *secbuf;
+
+ if ((secbuf = malloc(dl->d_secsize)) == NULL)
+ err(1, NULL);
+
+ /* Read MBR. */
+ len = pread(devfd, secbuf, dl->d_secsize, 0);
+ if (len != dl->d_secsize)
+ err(4, "can't read mbr");
+ memcpy(dp, &secbuf[DOSPARTOFF], sizeof(dp));
+
+ for (i = 0; i < NDOSPART; i++) {
+ if (dp[i].dp_typ == DOSPTYP_UNUSED)
+ continue;
+ if (dp[i].dp_typ == DOSPTYP_FAT16L ||
+ dp[i].dp_typ == DOSPTYP_FAT32L ||
+ dp[i].dp_typ == DOSPTYP_FAT16B)
+ start = letoh32(dp[i].dp_start);
+ }
+
+ free(secbuf);
+
+ if (start) {
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ if (DL_GETPSIZE(&dl->d_partitions[i]) > 0 &&
+ DL_GETPOFFSET(&dl->d_partitions[i]) == start)
+ return ('a' + i);
+ }
+ }
+
+ return (-1);
+}