Booting off softraid on arm64 is supported but installboot(8) has no
softraid(4) support on arm64.

This means installboot always copies the single bootstrap efiboot on the
root volume and completely ignores softraid chunks, so root on softraid
on arm64 is unable to boot unless one manually drops into the installer
shell and runs `installboot -r/mnt ...' on each chunk before reboot.

Add support for this by copying over sparc64's softraid stage-1 code
as-is and making stage-2 a NOOP.

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

I have not yet tested this through install media builds, but
1. nuking all EFI partitions,
2. recreating EFI partitions on softraid chunks with installboot and
3. reinstalling efiboot with new installboot on the softraid volume
results in bootable root on softraid on arm64:

        # bioctl sd4                                                            
 
        Volume      Status               Size Device        
        softraid0 0 Online       107380400640 sd4     CRYPTO
                  0 Online       107380400640 0:0.0   noencl <sd0a>

        # dd if=/dev/zero of=/dev/sd4i bs=1m count=1 
        1+0 records in
        1+0 records out
        1048576 bytes transferred in 0.073 secs (14181527 bytes/sec)

        # dd if=/dev/zero of=/dev/sd0i bs=1m count=1
        1+0 records in
        1+0 records out
        1048576 bytes transferred in 0.028 secs (37360833 bytes/sec)

        # ./obj/installboot -p sd0

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

Feedback? OK (once I've build a miniroot and tested a fresh install)?


Index: Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/Makefile,v
retrieving revision 1.24
diff -u -p -r1.24 Makefile
--- Makefile    3 Feb 2022 10:21:13 -0000       1.24
+++ Makefile    10 Aug 2022 20:52:46 -0000
@@ -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
Index: efi_softraid.c
===================================================================
RCS file: efi_softraid.c
diff -N efi_softraid.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ efi_softraid.c      10 Aug 2022 21:59:34 -0000
@@ -0,0 +1,87 @@
+/*     $OpenBSD: sparc64_softraid.c,v 1.5 2020/06/08 19:17:12 kn Exp $ */
+/*
+ * Copyright (c) 2012 Joel Sing <js...@openbsd.org>
+ * Copyright (c) 2022 Klemens Nanni <k...@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.
+        */
+}

Reply via email to