diff options
author | 2020-06-27 15:35:27 +0000 | |
---|---|---|
committer | 2020-06-27 15:35:27 +0000 | |
commit | a284d5af97d5b29c3afb4a4a676706ecb8358a09 (patch) | |
tree | 2e836d1a3596d06918d2fd939893ae7c9a90e802 | |
parent | macro fixes; from matthew martin (diff) | |
download | wireguard-openbsd-a284d5af97d5b29c3afb4a4a676706ecb8358a09.tar.xz wireguard-openbsd-a284d5af97d5b29c3afb4a4a676706ecb8358a09.zip |
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
-rw-r--r-- | distrib/loongson/ramdisk/install.md | 20 | ||||
-rw-r--r-- | distrib/loongson/ramdisk/list | 3 | ||||
-rw-r--r-- | distrib/macppc/ramdisk/install.md | 16 | ||||
-rw-r--r-- | distrib/macppc/ramdisk/list | 3 | ||||
-rw-r--r-- | distrib/octeon/ramdisk/install.md | 16 | ||||
-rw-r--r-- | distrib/octeon/ramdisk/list | 3 | ||||
-rw-r--r-- | distrib/special/installboot/Makefile | 12 | ||||
-rw-r--r-- | usr.sbin/installboot/Makefile | 8 | ||||
-rw-r--r-- | usr.sbin/installboot/armv7_installboot.c | 8 | ||||
-rw-r--r-- | usr.sbin/installboot/i386_installboot.c | 6 | ||||
-rw-r--r-- | usr.sbin/installboot/i386_installboot.h | 4 | ||||
-rw-r--r-- | usr.sbin/installboot/i386_softraid.c | 4 | ||||
-rw-r--r-- | usr.sbin/installboot/loongson_installboot.c | 254 | ||||
-rw-r--r-- | usr.sbin/installboot/macppc_installboot.c | 244 | ||||
-rw-r--r-- | usr.sbin/installboot/octeon_installboot.c | 244 |
15 files changed, 787 insertions, 58 deletions
diff --git a/distrib/loongson/ramdisk/install.md b/distrib/loongson/ramdisk/install.md index ab8f254e106..48185267d35 100644 --- a/distrib/loongson/ramdisk/install.md +++ b/distrib/loongson/ramdisk/install.md @@ -1,4 +1,4 @@ -# $OpenBSD: install.md,v 1.27 2017/01/22 23:43:54 rpe Exp $ +# $OpenBSD: install.md,v 1.28 2020/06/27 15:35:27 deraadt Exp $ # # Copyright (c) 1996 The NetBSD Foundation, Inc. # All rights reserved. @@ -32,21 +32,11 @@ # md_installboot() { - local _disk=$1 - - # Use cat below to avoid holes created by cp(1) - if mount -t ext2fs /dev/${_disk}i /mnt2 && - mkdir -p /mnt2/boot && - cat /mnt/usr/mdec/boot > /mnt2/boot/boot && - { [[ $(sysctl -n hw.product) != Gdium ]] || - cp /mnt/bsd /mnt2/boot/bsd; }; then - umount /mnt2 - return + if ! installboot -r /mnt ${1}; then + echo "\nFailed to install bootblocks." + echo "You will not be able to boot OpenBSD from ${1}." + exit fi - - echo "Failed to install bootblocks." - echo "You will not be able to boot OpenBSD from $_disk." - exit } md_prep_fdisk() { diff --git a/distrib/loongson/ramdisk/list b/distrib/loongson/ramdisk/list index 744ec387529..a3922bbc08b 100644 --- a/distrib/loongson/ramdisk/list +++ b/distrib/loongson/ramdisk/list @@ -1,4 +1,4 @@ -# $OpenBSD: list,v 1.34 2019/06/07 14:39:57 deraadt Exp $ +# $OpenBSD: list,v 1.35 2020/06/27 15:35:27 deraadt Exp $ SRCDIRS distrib/special @@ -62,6 +62,7 @@ LINK instbin usr/bin/sed LINK instbin usr/bin/signify LINK instbin usr/bin/tee LINK instbin usr/sbin/chroot +LINK instbin usr/sbin/installboot LINK instbin usr/sbin/pwd_mkdb ARGVLINK ksh -sh SPECIAL rm bin/md5 diff --git a/distrib/macppc/ramdisk/install.md b/distrib/macppc/ramdisk/install.md index a23199712fe..48b7e72c9d6 100644 --- a/distrib/macppc/ramdisk/install.md +++ b/distrib/macppc/ramdisk/install.md @@ -1,4 +1,4 @@ -# $OpenBSD: install.md,v 1.72 2017/12/01 18:13:48 stsp Exp $ +# $OpenBSD: install.md,v 1.73 2020/06/27 15:35:29 deraadt Exp $ # # Copyright (c) 1996 The NetBSD Foundation, Inc. # All rights reserved. @@ -36,16 +36,10 @@ MDXDM=y NCPU=$(sysctl -n hw.ncpufound) md_installboot() { - local _disk=$1 - - # If there is an MSDOS partition on the boot disk, copy ofwboot - # into it. - if disk_has $_disk mbr openbsd; then - if mount /dev/${_disk}i /mnt2 >/dev/null 2>&1; then - # Use cat to avoid holes created by cp(1) - cat /mnt/usr/mdec/ofwboot > /mnt2/ofwboot - umount /mnt2 - fi + if ! installboot -r /mnt ${1}; then + echo "\nFailed to install bootblocks." + echo "You will not be able to boot OpenBSD from ${1}." + exit fi } diff --git a/distrib/macppc/ramdisk/list b/distrib/macppc/ramdisk/list index 72e7c40cb47..4757e6e59c5 100644 --- a/distrib/macppc/ramdisk/list +++ b/distrib/macppc/ramdisk/list @@ -1,4 +1,4 @@ -# $OpenBSD: list,v 1.72 2019/06/07 14:39:57 deraadt Exp $ +# $OpenBSD: list,v 1.73 2020/06/27 15:35:29 deraadt Exp $ SRCDIRS distrib/special @@ -60,6 +60,7 @@ LINK instbin usr/bin/sed LINK instbin usr/bin/signify LINK instbin usr/bin/tee LINK instbin usr/sbin/chroot +LINK instbin usr/sbin/installboot LINK instbin usr/sbin/pwd_mkdb ARGVLINK ksh -sh SPECIAL rm bin/md5 diff --git a/distrib/octeon/ramdisk/install.md b/distrib/octeon/ramdisk/install.md index dce66a9902e..cda3c5d3a2b 100644 --- a/distrib/octeon/ramdisk/install.md +++ b/distrib/octeon/ramdisk/install.md @@ -1,4 +1,4 @@ -# $OpenBSD: install.md,v 1.21 2020/06/24 03:54:02 deraadt Exp $ +# $OpenBSD: install.md,v 1.22 2020/06/27 15:35:29 deraadt Exp $ # # Copyright (c) 1996 The NetBSD Foundation, Inc. # All rights reserved. @@ -35,17 +35,11 @@ MDDKDEVS='/^[sw]d[0-9] /s/ .*//p;/^octcf[0-9] /s/ .*//p' NCPU=$(sysctl -n hw.ncpufound) md_installboot() { - local _disk=$1 - - if mount -t msdos /dev/${_disk}i /mnt2 && \ - cp /mnt/usr/mdec/boot /mnt2/boot; then - umount /mnt2 - return + if ! installboot -r /mnt ${1}; then + echo "\nFailed to install bootblocks." + echo "You will not be able to boot OpenBSD from ${1}." + exit fi - - echo "Failed to install bootblocks." - echo "You will not be able to boot OpenBSD from $_disk." - exit } md_prep_fdisk() { diff --git a/distrib/octeon/ramdisk/list b/distrib/octeon/ramdisk/list index f2b5f48821c..f7cd15c9cfe 100644 --- a/distrib/octeon/ramdisk/list +++ b/distrib/octeon/ramdisk/list @@ -1,4 +1,4 @@ -# $OpenBSD: list,v 1.27 2019/06/07 14:39:57 deraadt Exp $ +# $OpenBSD: list,v 1.28 2020/06/27 15:35:29 deraadt Exp $ SRCDIRS distrib/special @@ -59,6 +59,7 @@ LINK instbin usr/bin/sed LINK instbin usr/bin/signify LINK instbin usr/bin/tee LINK instbin usr/sbin/chroot +LINK instbin usr/sbin/installboot LINK instbin usr/sbin/pwd_mkdb ARGVLINK ksh -sh SPECIAL rm bin/md5 diff --git a/distrib/special/installboot/Makefile b/distrib/special/installboot/Makefile index 95977cc845d..2f518355cc3 100644 --- a/distrib/special/installboot/Makefile +++ b/distrib/special/installboot/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.11 2019/05/11 07:18:15 deraadt Exp $ +# $OpenBSD: Makefile,v 1.12 2020/06/27 15:35:29 deraadt Exp $ .PATH: ${.CURDIR}/../../../usr.sbin/installboot @@ -21,11 +21,11 @@ SRCS += i386_softraid.c .endif .if ${MACHINE} == "arm64" -SRCS += stubs.c +SRCS += armv7_installboot.c .endif .if ${MACHINE} == "armv7" -SRCS += stubs.c +SRCS += armv7_installboot.c .endif .if ${MACHINE} == "hppa" @@ -46,7 +46,7 @@ SRCS += landisk_installboot.c .endif .if ${MACHINE} == "loongson" -SRCS += stubs.c +SRCS += octeon_installboot.c .endif .if ${MACHINE} == "luna88k" @@ -54,11 +54,11 @@ SRCS += stubs.c .endif .if ${MACHINE} == "macppc" -SRCS += stubs.c +SRCS += macppc_installboot.c .endif .if ${MACHINE} == "octeon" -SRCS += stubs.c +SRCS += octeon_installboot.c .endif .if ${MACHINE} == "sgi" 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); +} |