On Thu, Aug 11, 2022 at 03:51:17PM +0000, Klemens Nanni wrote:
> 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)?

This part itself also works in my miniroot tests, but not alone.

installboot(8)'s `-p' for creating the EFI system partition needs to
be made softraid(4) aware as well;  it currently leaves the softraid
chunk's 'i' partition untouched.

Finished diff for that follows soon.

> 
> 
> 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