Hi
Since we have efiboot creating a multiboot environment on amd64/i386
became simpler. One obstacle is that (all?) OSs write their bootloader
to the default loction efi/boot/ on the EFI Sys partition.
Some OSs also create an efi/XXX directory where they put most of their
stuff (centos, ubuntu, win 10, ...).
With the below patch OpenBSDs installboot places the efiboot binaries in
the addidional location efi/openbsd. A user that configures a multiboot
environment can then register the OS specific loader with the EFI firmware.
With that OpenBSD will just boot after an upgrade without manual intervention
and the installation of an addition OS will not break OpenBSD boot process.
Remi
Index: i386_installboot.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/i386_installboot.c,v
retrieving revision 1.26
diff -u -p -r1.26 i386_installboot.c
--- i386_installboot.c 28 Dec 2015 23:00:29 -0000 1.26
+++ i386_installboot.c 28 Jan 2016 07:48:31 -0000
@@ -223,9 +223,10 @@ write_efisystem(struct disklabel *dl, ch
static char *newfsfmt ="/sbin/newfs_msdos %s >/dev/null";
struct msdosfs_args args;
char cmd[60];
- char dst[50]; /* /tmp/installboot.XXXXXXXXXX/efi/BOOT/BOOTIA32.EFI */
+ char dst[50]; /* /tmp/installboot.XXXXXXXXXX/efi/BOOT/BOOTIA32.EFI
*/
+ char dst2[53]; /* /tmp/installboot.XXXXXXXXXX/efi/OPENBSD/BOOTIA32.EFI
*/
char *src;
- size_t mntlen, pathlen, srclen;
+ size_t mntlen, pathlen, pathlen2, srclen;
int rslt;
src = NULL;
@@ -286,7 +287,7 @@ write_efisystem(struct disklabel *dl, ch
}
}
- /* Create "/efi/BOOT" directory in <duid>.<part>. */
+ /* Create "/efi/BOOT" and "/efi/OPENBSD" directory in <duid>.<part>. */
if (strlcat(dst, "/efi", sizeof(dst)) >= sizeof(dst)) {
rslt = -1;
warn("unable to build /efi directory");
@@ -297,6 +298,7 @@ write_efisystem(struct disklabel *dl, ch
warn("mkdir('%s') failed", dst);
goto umount;
}
+ memcpy(dst2, dst, sizeof(dst));
if (strlcat(dst, "/BOOT", sizeof(dst)) >= sizeof(dst)) {
rslt = -1;
warn("unable to build /BOOT directory");
@@ -307,18 +309,35 @@ write_efisystem(struct disklabel *dl, ch
warn("mkdir('%s') failed", dst);
goto umount;
}
+ if (strlcat(dst2, "/OPENBSD", sizeof(dst2)) >= sizeof(dst2)) {
+ rslt = -1;
+ warn("unable to build /OPENBSD directory");
+ goto umount;
+ }
+ rslt = mkdir(dst2, 0);
+ if (rslt == -1 && errno != EEXIST) {
+ warn("mkdir('%s') failed", dst2);
+ goto umount;
+ }
/*
- * Copy BOOTIA32.EFI and BOOTX64.EFI to /efi/BOOT/.
+ * Copy BOOTIA32.EFI and BOOTX64.EFI to /efi/BOOT/ and /efi/OPENBSD.
*
* N.B.: BOOTIA32.EFI is longer than BOOTX64.EFI, so src can be reused!
*/
pathlen = strlen(dst);
if (strlcat(dst, "/BOOTIA32.EFI", sizeof(dst)) >= sizeof(dst)) {
rslt = -1;
- warn("unable to build /BOOTIA32.EFI path");
+ warn("unable to build /efi/BOOT/BOOTIA32.EFI path");
+ goto umount;
+ }
+ pathlen2 = strlen(dst2);
+ if (strlcat(dst2, "/BOOTIA32.EFI", sizeof(dst2)) >= sizeof(dst2)) {
+ rslt = -1;
+ warn("unable to build /efi/OPENBSD/BOOTIA32.EFI path");
goto umount;
}
+
src = fileprefix(root, "/usr/mdec/BOOTIA32.EFI");
if (src == NULL) {
rslt = -1;
@@ -326,19 +345,28 @@ write_efisystem(struct disklabel *dl, ch
}
srclen = strlen(src);
if (verbose)
- fprintf(stderr, "%s %s to %s\n",
- (nowrite ? "would copy" : "copying"), src, dst);
+ fprintf(stderr, "%s %s to %s and %s\n",
+ (nowrite ? "would copy" : "copying"), src, dst, dst2);
if (!nowrite) {
rslt = filecopy(src, dst);
if (rslt == -1)
goto umount;
+ rslt = filecopy(src, dst2);
+ if (rslt == -1)
+ goto umount;
}
src[srclen - strlen("/BOOTIA32.EFI")] = '\0';
dst[pathlen] = '\0';
if (strlcat(dst, "/BOOTX64.EFI", sizeof(dst)) >= sizeof(dst)) {
rslt = -1;
- warn("unable to build /BOOTX64.EFI dst path");
+ warn("unable to build /efi/BOOT/BOOTX64.EFI dst path");
+ goto umount;
+ }
+ dst2[pathlen2] = '\0';
+ if (strlcat(dst2, "/BOOTX64.EFI", sizeof(dst2)) >= sizeof(dst2)) {
+ rslt = -1;
+ warn("unable to build /efi/OPENBSD/BOOTX64.EFI dst path");
goto umount;
}
if (strlcat(src, "/BOOTX64.EFI", srclen+1) >= srclen+1) {
@@ -347,10 +375,13 @@ write_efisystem(struct disklabel *dl, ch
goto umount;
}
if (verbose)
- fprintf(stderr, "%s %s to %s\n",
- (nowrite ? "would copy" : "copying"), src, dst);
+ fprintf(stderr, "%s %s to %s and %s\n",
+ (nowrite ? "would copy" : "copying"), src, dst, dst2);
if (!nowrite) {
rslt = filecopy(src, dst);
+ if (rslt == -1)
+ goto umount;
+ rslt = filecopy(src, dst2);
if (rslt == -1)
goto umount;
}