Add initial piece for softraid(4) support on arm64
authorkn <kn@openbsd.org>
Mon, 15 Aug 2022 17:06:43 +0000 (17:06 +0000)
committerkn <kn@openbsd.org>
Mon, 15 Aug 2022 17:06:43 +0000 (17:06 +0000)
arm64 is the only currently supported OpenBSD platform which both
a) supports booting off root on softraid(4) (kernel and bootloader) and
b) is an EFI platform (as far as installboot(8) is concerned).

Currently, installboot treats softraid root volumes as regular devices,
ignoring ignores chunk devices completely.

Teach installboot the first bits of softraid support for EFI:
installing the single-stage boot loader on chunks rather than the volume.

Copy over sparc64's softraid stage-1 code as-is and make its stage-2 a NOOP:

# ./obj/installboot -v sd4
Using / as root
installing bootstrap on /dev/rsd4c
using first-stage /usr/mdec/BOOTAA64.EFI
sd4: softraid volume with 1 disk(s)
sd0a: installing boot blocks on /dev/rsd0c
copying /usr/mdec/BOOTAA64.EFI to /tmp/installboot.KuBD4zkfpM/efi/boot/bootaa64.efi
writing /tmp/installboot.KuBD4zkfpM/efi/boot/startup.nsh

arm64 miniroot fits and boots with this.

OK stsp

As of now, EFI partitions must still be created manually as installboot's
'-p' does not support softraid at all (next missing piece for root on
softraid on arm64 installations to work out-of-the-box).

usr.sbin/installboot/Makefile
usr.sbin/installboot/efi_softraid.c [new file with mode: 0644]

index 0d2d845..c4c5ea3 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.24 2022/02/03 10:21:13 visa Exp $
+#      $OpenBSD: Makefile,v 1.25 2022/08/15 17:06:43 kn Exp $
 
 PROG=          installboot
 SRCS=          installboot.c util.c
@@ -16,6 +16,10 @@ SRCS += i386_installboot.c
 SRCS += i386_nlist.c
 SRCS += i386_softraid.c
 .elif ${MACHINE} == "armv7" || ${MACHINE} == "arm64" || ${MACHINE} == "riscv64"
+.  if ${MACHINE} == "arm64"
+CFLAGS += -DSOFTRAID
+SRCS += efi_softraid.c
+.  endif
 SRCS += efi_installboot.c
 .elif ${MACHINE} == "hppa"
 CFLAGS += -DBOOTSTRAP
diff --git a/usr.sbin/installboot/efi_softraid.c b/usr.sbin/installboot/efi_softraid.c
new file mode 100644 (file)
index 0000000..259df18
--- /dev/null
@@ -0,0 +1,87 @@
+/*     $OpenBSD: efi_softraid.c,v 1.1 2022/08/15 17:06:43 kn Exp $     */
+/*
+ * Copyright (c) 2012 Joel Sing <jsing@openbsd.org>
+ * Copyright (c) 2022 Klemens Nanni <kn@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/disklabel.h>
+#include <sys/ioctl.h>
+
+#include <dev/biovar.h>
+#include <dev/softraidvar.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <util.h>
+#include <unistd.h>
+
+#include "installboot.h"
+
+void
+sr_install_bootblk(int devfd, int vol, int disk)
+{
+       struct bioc_disk bd;
+       char *realdev;
+       int diskfd;
+       char part;
+
+       /* Get device name for this disk/chunk. */
+       memset(&bd, 0, sizeof(bd));
+       bd.bd_volid = vol;
+       bd.bd_diskid = disk;
+       if (ioctl(devfd, BIOCDISK, &bd) == -1)
+               err(1, "BIOCDISK");
+
+       /* Check disk status. */
+       if (bd.bd_status != BIOC_SDONLINE && bd.bd_status != BIOC_SDREBUILD) {
+               fprintf(stderr, "softraid chunk %u not online - skipping...\n",
+                   disk);
+               return;
+       }
+
+       if (strlen(bd.bd_vendor) < 1)
+               errx(1, "invalid disk name");
+       part = bd.bd_vendor[strlen(bd.bd_vendor) - 1];
+       if (part < 'a' || part >= 'a' + MAXPARTITIONS)
+               errx(1, "invalid partition %c\n", part);
+       bd.bd_vendor[strlen(bd.bd_vendor) - 1] = '\0';
+
+       /* Open device. */
+       if ((diskfd = opendev(bd.bd_vendor, (nowrite ? O_RDONLY : O_RDWR),
+           OPENDEV_PART, &realdev)) == -1)
+               err(1, "open: %s", realdev);
+
+       if (verbose)
+               fprintf(stderr, "%s%c: installing boot blocks on %s\n",
+                   bd.bd_vendor, part, realdev);
+
+       /* Write boot blocks to device. */
+       md_installboot(diskfd, realdev);
+
+       close(diskfd);
+}
+
+void
+sr_install_bootldr(int devfd, char *dev)
+{
+       /*
+        * EFI platforms have a single stage bootstrap.
+        * sr_install_bootblk() installs it on each softraid chunk.
+        * The softraid volume does not require any bootstrap code.
+        */
+}