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(). 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 19 Nov 2022 19:19:28 -0000 @@ -194,6 +194,8 @@ write_filesystem(struct disklabel *dl, c struct msdosfs_args args; char cmd[60]; char dst[PATH_MAX]; + char fw[PATH_MAX]; + struct stat st; char *src; size_t mntlen, pathlen, srclen; int rslt; @@ -248,7 +250,46 @@ write_filesystem(struct disklabel *dl, c } } + /* Copy apple-boot firmware to /m1n1/boot.bin if available */ + pathlen = strlen(dst); + if (strlcat(dst, "/m1n1", sizeof(dst)) >= sizeof(dst)) { + rslt = -1; + warn("unable to build /m1n1 path"); + goto umount; + } + rslt = snprintf(fw, PATH_MAX, "%s/%s", root, "/etc/firmware"); + if (rslt < 0 || rslt >= PATH_MAX) { + rslt = -1; + warn("unable to build /etc/firmware path"); + goto umount; + } + if ((stat(fw, &st) == 0) && S_ISDIR(st.st_mode) && + (stat(dst, &st) == 0) && S_ISDIR(st.st_mode)) { + src = fileprefix(fw, "/apple-boot.bin"); + if (src == NULL) { + rslt = -1; + goto umount; + } + if (access(src, R_OK) == 0) { + if (strlcat(dst, "/boot.bin", + sizeof(dst)) >= sizeof(dst)) { + rslt = -1; + warn("unable to build /m1n1/boot.bin path"); + goto umount; + } + 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; + } + } + /* Create "/efi/boot" directory in <duid>.<part>. */ + dst[pathlen] = '\0'; if (strlcat(dst, "/efi", sizeof(dst)) >= sizeof(dst)) { rslt = -1; warn("unable to build /efi directory");