[PATCH] BIOS boot vs EFI system partition mountpoint
Taylor R Campbell <[email protected]> Sat, 20 Aug 2022 12:00:31 +0000
| Newsgroups | gmane.os.netbsd.ports.x86-64,gmane.os.netbsd.ports.i386 |
|---|---|
| Message-ID | <[email protected]> |
I'd like to have a standard mount point for the EFI system partition
on platforms with EFI boot. On NetBSD/arm, this is /boot (which is
also shared with non-EFI boot on some Arm boards), and on NetBSD/riscv
it'll probably be the same eventually.
Currently on x86, BIOS boot requires a secondary bootloader at /boot
in the root file system. EFI boot doesn't require any secondary
bootloader, so /boot could also be the ESP mountpoint in principle,
but it would pose a conflict for a hybrid image that boots with
_either_ BIOS or EFI and has the ESP mounted.
I propose to change NetBSD/x86 BIOS boot so it looks for the secondary
bootloader at /biosboot instead of /boot, but falls back to /boot.
That way, a hybrid image can have /biosboot as well as the ESP mounted
at /boot, and we can have /boot as the standard mount point for ESP on
platforms with EFI boot.
The attached patch changes bootxx_* -- except bootxx_fat12/fat16[*] --
to try /biosboot first and then fall back to /boot, and patches
sysinst to install the BIOS bootloader at /biosboot instead of /boot.
I've tested BIOS and EFI boot under qemu with the same image.
OK?
[*] I suspect tbootxx_fat12/fat16 have tighter space constraints.
It's possible, even if there are space constraints, that we could
fit logic to try /biosboot first and then /boot. But they are
also hand-written assembly, I don't know how to test them, and I
doubt they're relevant on any hybrid images anyway, so I didn't
change them.
biosboot.patch
(text/plain, 6.4 KB)
From 693c3b6ff4b505958b73d73600b9002a830b71af Mon Sep 17 00:00:00 2001 From: Taylor R Campbell <[email protected]> Date: Thu, 18 Aug 2022 13:53:53 +0000 Subject: [PATCH] x86: Move the secondary BIOS bootloader from /boot to /biosboot. This way /boot can be freed up as a standard mount point for the EFI system partition, like evbarm uses. The bootxx_* primary BIOS bootloaders will try /biosboot first to find the secondary bootloader, and fall back to /boot if it does not exist, so that existing file systems will continue to function. Exception: bootxx_fat12/fat16 currently don't try /biosboot, but I don't think they are relevant on any hybrid images for systems that might use BIOS or UEFI boot, and I suspect they may be size- constrained. --- share/man/man8/man8.x86/boot.8 | 54 ++++++++++++++++++++++++++---- sys/arch/i386/stand/bootxx/boot1.c | 38 +++++++++++++++------ usr.sbin/sysinst/arch/i386/md.c | 4 +-- 3 files changed, 76 insertions(+), 20 deletions(-) diff --git a/share/man/man8/man8.x86/boot.8 b/share/man/man8/man8.x86/boot.8 index b2b9029153fc..b48eec53b296 100644 --- a/share/man/man8/man8.x86/boot.8 +++ b/share/man/man8/man8.x86/boot.8 @@ -51,7 +51,7 @@ can use any of the following boot procedures, depending on what the hardware and .Tn BIOS support: .Bl -tag -width "x86/pxeboot(8)" -.It boot +.It biosboot bootstrap .Nx from the system @@ -82,7 +82,27 @@ and Normally, the system will reboot itself at power-up or after crashes. An automatic consistency check of the file systems will be performed, and unless this fails, the system will resume multi-user operations. -.Ss Cold starts +.Ss UEFI boot +Modern x86 systems use the Unified Extensible Firmware Interface to +boot +.Pq Sq efiboot . +The machine's firmware will open the EFI system partition in a GPT +.Pq Xr gpt 8 +and execute +.Nx Ns 's +boot loader at +.Pa EFI/boot/bootia32.efi +.Pq i386 +or +.Pa EFI/boot/bootx64.efi +.Pq amd64 . +With UEFI boot there is no MBR boot block and no separate primary and +secondary boot loader; +.Pa bootia32.efi +or +.Pa bootx64.efi +will load and execute the kernel directly. +.Ss Cold starts with legacy BIOS boot The 386 .Tn "PC AT" clones attempt to boot the floppy disk drive A (otherwise known as drive @@ -778,8 +798,13 @@ So you can only boot from unit 0. .El .Sh FILES .Bl -tag -width /usr/mdec/bootxx_fstype -compact +.It Pa /biosboot +secondary boot program code loaded by the primary bootstrap for BIOS +boot +(not needed for EFI boot) .It Pa /boot -boot program code loaded by the primary bootstrap +EFI system partition mount point, or legacy location of secondary boot +program for BIOS boot .It Pa /boot.cfg optional configuration file .It Pa /netbsd @@ -787,7 +812,10 @@ system code .It Pa /netbsd.gz gzip-compressed system code .It Pa /usr/mdec/boot -master copy of the boot program (copy to /boot) +.\" XXX should rename to /usr/mdec/biosboot +master copy of the secondary boot program for BIOS boot \(em copy to +.Pa /biosboot +to use .It Pa /usr/mdec/bootxx_fstype primary bootstrap for file system type fstype, copied to the start of the @@ -802,7 +830,7 @@ bootstraps for and .Nx Ns /amd64 , which should be copied to the -.Pa /EFI/boot +.Pa EFI/boot directory in a .Tn FAT formatted partition of type @@ -817,10 +845,15 @@ section). .Nx .Tn UEFI bootstrap reads its configuration from the -.Pa /EFI/NetBSD/boot.cfg +.Pa EFI/NetBSD/boot.cfg file in the .Tn EFI -partition. +partition; +if that file does not exist, it reads +.Pa /boot.cfg +in the +.Nx +file system instead. .El .Sh SEE ALSO .Xr ddb 4 , @@ -839,6 +872,13 @@ partition. .Xr x86/multiboot 8 , .Xr x86/pxeboot 8 , .Xr boothowto 9 +.Rs +.%Q UEFI Forum, Inc. +.%T Unified Extensible Firmware Interface (UEFI) Specification +.%N Version 2.9 +.%D March 2021 +.%U https://uefi.org/sites/default/files/resources/UEFI_Spec_2_9_2021_03_18.pdf +.Re .Sh BUGS The kernel file name must be specified before, not after, the boot options. Any diff --git a/sys/arch/i386/stand/bootxx/boot1.c b/sys/arch/i386/stand/bootxx/boot1.c index f563eb46aa18..91f456af4a32 100644 --- a/sys/arch/i386/stand/bootxx/boot1.c +++ b/sys/arch/i386/stand/bootxx/boot1.c @@ -54,9 +54,25 @@ extern void putstr(const char *); extern struct disklabel ptn_disklabel; static int -ob(void) +ob1(const char *p, struct stat *st) { - return open("boot", 0); + int fd; + + if ((fd = open(p, 0)) == -1) + return -1; + if (fstat(fd, st) == -1) + return -1; + return fd; +} + +static int +ob(struct stat *st) +{ + int fd; + + if ((fd = ob1("biosboot", st)) != -1) + return fd; + return ob1("boot", st); } const char * @@ -77,7 +93,7 @@ boot1(uint32_t biosdev, uint64_t *sector) * We default to the filesystem at the start of the * MBR partition */ - fd = ob(); + fd = ob(&sb); if (fd != -1) goto done; /* @@ -87,7 +103,7 @@ boot1(uint32_t biosdev, uint64_t *sector) * magic number is absent.) */ bios_sector += RF_PROTECTED_SECTORS; - fd = ob(); + fd = ob(&sb); if (fd != -1) goto done; /* @@ -103,23 +119,23 @@ boot1(uint32_t biosdev, uint64_t *sector) if (ptn_disklabel.d_partitions[0].p_fstype == FS_RAID) bios_sector += RF_PROTECTED_SECTORS; - fd = ob(); - + fd = ob(&sb); done: - if (fd == -1 || fstat(fd, &sb) == -1) - return "Can't open /boot\r\n"; + if (fd == -1) + return "Can't open biosboot\r\n"; + /* XXX if (!S_ISREG(sb.st_mode)) ... */ biosdev = (uint32_t)sb.st_size; #if 0 if (biosdev > SECONDARY_MAX_LOAD) - return "/boot too large\r\n"; + return "biosboot too large\r\n"; #endif if (read(fd, (void *)SECONDARY_LOAD_ADDRESS, biosdev) != biosdev) - return "/boot load failed\r\n"; + return "biosboot load failed\r\n"; if (*(uint32_t *)(SECONDARY_LOAD_ADDRESS + 4) != X86_BOOT_MAGIC_2) - return "Invalid /boot file format\r\n"; + return "Invalid biosboot file format\r\n"; /* We need to jump to the secondary bootstrap in realmode */ return 0; diff --git a/usr.sbin/sysinst/arch/i386/md.c b/usr.sbin/sysinst/arch/i386/md.c index 1078e76edaca..f04347e6aa46 100644 --- a/usr.sbin/sysinst/arch/i386/md.c +++ b/usr.sbin/sysinst/arch/i386/md.c @@ -283,9 +283,9 @@ update_bios_boot(struct install_partition_desc *install, bool use_target_files) } if (use_target_files) - ret = cp_within_target("/usr/mdec/boot", "/", 0); + ret = cp_within_target("/usr/mdec/boot", "/biosboot", 0); else - ret = cp_to_target("/usr/mdec/boot", "/"); + ret = cp_to_target("/usr/mdec/boot", "/biosboot"); if (ret) return ret; if (pm && pm->no_part)