> Date: Mon, 21 Nov 2022 15:42:37 +0100
> From: Tobias Heider <tobias.hei...@stusta.de>
> 
> On Sat, Nov 19, 2022 at 08:27:18PM +0100, Tobias Heider wrote:
> > On Sat, Nov 19, 2022 at 07:25:52PM +0100, Mark Kettenis wrote:
> > > > Date: Sat, 19 Nov 2022 18:44:19 +0100
> > > > From: Tobias Heider <tobias.hei...@stusta.de>
> > > > 
> > > > On Sat, Nov 19, 2022 at 06:33:51PM +0100, Mark Kettenis wrote:
> > > > > > Date: Sat, 19 Nov 2022 18:26:36 +0100
> > > > > > From: Tobias Heider <tobias.hei...@stusta.de>
> > > > > > 
> > > > > > Here is the promised last diff we need to enable Apple M* 
> > > > > > bootloader updates.
> > > > > > 
> > > > > > With this, installboot(8) will pick up apple-boot.bin from the 
> > > > > > firmware
> > > > > > directory and writes it to $ESP/m1n1/boot.bin if both file and 
> > > > > > target
> > > > > > directory exist.
> > > > > > Creation of the m1n1/ directory is expected to happen during the 
> > > > > > initial
> > > > > > Asahi Linux EFI environment installation so it is safe to assume it 
> > > > > > is
> > > > > > already there when we need it.
> > > > > > 
> > > > > > Running this on my M2 gives me:
> > > > > > 
> > > > > > kischt# installboot -v sd0  
> > > > > > Using / as root
> > > > > > installing bootstrap on /dev/rsd0c
> > > > > > using first-stage /usr/mdec/BOOTAA64.EFI
> > > > > > copying /etc/firmware/apple-boot.bin to 
> > > > > > /tmp/installboot.0JSQ0XrWRB/m1n1/boot.bin
> > > > > > copying /usr/mdec/BOOTAA64.EFI to 
> > > > > > /tmp/installboot.0JSQ0XrWRB/efi/boot/bootaa64.efi
> > > > > > writing /tmp/installboot.0JSQ0XrWRB/efi/boot/startup.nsh
> > > > > 
> > > > > Hmm...
> > > > > 
> > > > > > Index: efi_installboot.c
> > > > > > ===================================================================
> > > > > > RCS file: /cvs/src/usr.sbin/installboot/efi_installboot.c,v
> > > > > > retrieving revision 1.6
> > > > > > diff -u -p -r1.6 efi_installboot.c
> > > > > > --- efi_installboot.c       14 Sep 2022 16:43:00 -0000      1.6
> > > > > > +++ efi_installboot.c       19 Nov 2022 16:45:36 -0000
> > > > > > @@ -191,6 +191,7 @@ write_filesystem(struct disklabel *dl, c
> > > > > >     struct msdosfs_args args;
> > > > > >     char cmd[60];
> > > > > >     char dst[PATH_MAX];
> > > > > > +   struct stat st;
> > > > > >     char *src;
> > > > > >     size_t mntlen, pathlen, srclen;
> > > > > >     int rslt;
> > > > > > @@ -245,7 +246,36 @@ write_filesystem(struct disklabel *dl, c
> > > > > >             }
> > > > > >     }
> > > > > >  
> > > > > > +   /* Copy apple-boot firmware to /m1n1/boot.bin if available */
> > > > > > +   src = fileprefix(root, "/etc/firmware/apple-boot.bin");
> > > > > > +   if (src == NULL) {
> > > > > > +           rslt = -1;
> > > > > > +           goto umount;
> > > > > 
> > > > > Doesn't this mean that if /etc/firmware/apple-boot.bin doesn't exist,
> > > > > we won't write the OpenBSD bootloader to the filesystem?  That would
> > > > > be wrong.
> > > > > 
> > > > > So I think the Apple "magic" needs to be done at the end of the
> > > > > function.
> > > > 
> > > > That is what I also first thought, but fileprefix() just concats the 
> > > > strings
> > > > and doesn't actually touch the file system.  This is also why I added 
> > > > my own
> > > > stat() && S_ISDIR() check below to make sure the directory exists.
> > > > 
> > > > Wit apple-boot manually deleted I get:
> > > > 
> > > > kischt# installboot -v sd0            
> > > > Using / as root
> > > > installing bootstrap on /dev/rsd0c
> > > > using first-stage /usr/mdec/BOOTAA64.EFI
> > > > copying /usr/mdec/BOOTAA64.EFI to 
> > > > /tmp/installboot.Tm5s4GRaRT/efi/boot/bootaa64.efi
> > > > writing /tmp/installboot.Tm5s4GRaRT/efi/boot/startup.nsh
> > > 
> > > Hmm, but it will still fail if the /etc/firmware directory doesn't
> > > exist under the "root".  Which may be the case if you are using the -r
> > > option?
> > > 
> > 
> > Right, regress also trips over this.
> > 
> > Moving the whole block inside fileprefix() != NULL is not enough since
> > that would still print the error message.  We might have to add our own
> > check fore $root/etc/firmware, although that duplicates some of the
> > code in fileprefix().
> > 
> 
> Here is a more cleaned up version of the previous diff.  I moved all the
> firmware logic to a new write_firmware() function.  This should be easy
> to extend if we decide to ship more firmware this way.
> 
> The diff passes regress and manual tests with and without $ESP/m1n1/,
> /etc/firmware and /etc/firmware/apple-boot.bin.
> 
> ok?

I like this a lot better.  Two nits below, but either way, ok kettenis@

> Index: efi_installboot.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/installboot/efi_installboot.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 efi_installboot.c
> --- efi_installboot.c 6 Nov 2022 12:33:41 -0000       1.7
> +++ efi_installboot.c 21 Nov 2022 14:21:29 -0000
> @@ -70,6 +70,7 @@
>  
>  static int   create_filesystem(struct disklabel *, char);
>  static void  write_filesystem(struct disklabel *, char);
> +static int   write_firmware(char *, char *);
>  static int   findgptefisys(int, struct disklabel *);
>  static int   findmbrfat(int, struct disklabel *);
>  
> @@ -308,6 +309,13 @@ write_filesystem(struct disklabel *dl, c
>                       goto umount;
>       }
>  
> +     dst[mntlen] = '\0';
> +     if (write_firmware(root, dst) == -1) {
> +             warn("unable to write firmware");
> +             rslt = -1;
> +             goto umount;
> +     }
> +
>       rslt = 0;
>  
>  umount:
> @@ -325,6 +333,61 @@ rmdir:
>  
>       if (rslt == -1)
>               exit(1);
> +}
> +
> +static int
> +write_firmware(char *root, char *mnt)
> +{
> +     char dst[PATH_MAX];
> +     char fw[PATH_MAX];
> +     char *src;
> +     struct stat st;
> +     int rslt;
> +
> +     src = NULL;

This is pointless.  I realize the write_filesystem() function does
this as well.  But unless someone explains why it should be kept, I'd
delete it.

> +     strlcpy(dst, mnt, sizeof(dst));
> +
> +     /* Skip if no /etc/firmware exists */
> +     rslt = snprintf(fw, sizeof(fw), "%s/%s", root, "etc/firmware");
> +     if (rslt < 0 || rslt >= PATH_MAX) {
> +             warn("unable to build /etc/firmware path");
> +             return -1;
> +     }
> +     if ((stat(fw, &st) != 0) || !S_ISDIR(st.st_mode))
> +             return 0;
> +
> +     /* Copy apple-boot firmware to /m1n1/boot.bin if available */
> +     src = fileprefix(fw, "/apple-boot.bin");
> +     if (src == NULL)
> +             return -1;
> +     if (access(src, R_OK) == 0) {
> +             if (strlcat(dst, "/m1n1", sizeof(dst)) >= sizeof(dst)) {
> +                     rslt = -1;
> +                     warn("unable to build /m1n1 path");
> +                     goto cleanup;
> +             }
> +             if ((stat(dst, &st) != 0) || !S_ISDIR(st.st_mode)) {
> +                     rslt = 0;
> +                     goto cleanup;
> +             }
> +             if (strlcat(dst, "/boot.bin", sizeof(dst)) >= sizeof(dst)) {
> +                     rslt = -1;
> +                     warn("unable to build /m1n1/boot.bin path");
> +                     goto cleanup;
> +             }
> +             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 cleanup;
> +     }
> +     rslt = 0;

Add a blank line here to make the label stand out a bit more?

> + cleanup:
> +     free(src);
> +     return rslt;
>  }
>  
>  /*
> 
> 

Reply via email to