RFC: Handling of multiple EFI System Partitions

Mark Kettenis mark.kettenis at xs4all.nl
Mon Dec 19 11:51:44 CET 2022


> Date: Sun, 18 Dec 2022 20:40:20 +0100
> From: Heinrich  Schuchardt <xypron.glpk at gmx.de>

Hi Heinrich,

Hector already provided a more elaborate explanation of why we need
multiple ESPs.  But here is my repsonse to your comment about the
fallback path that he didn't address.

> Am 18. Dezember 2022 15:21:06 MEZ schrieb Mark Kettenis <mark.kettenis at xs4all.nl>:
> >The Asahi installer, which is what most people use to get their Apple
> >Silicon Mac into a state where it is possible to install another OS on
> >the machine, offers the posibility to create multiple OS installs.
> >For each of these it creates a separate APFS partition (which holds
> >among other things, some essential system firmware) and separate EFI
> >System Partitions.  This has a few benefits:
> >
> >* It allows control over which version of the system firmware is used
> >  by the OS.  This is especially important for things like the GPU and
> >  DCP (display controller) firmware, where the firmware interface
> >  isn't exactly what we'd call "stable".  This way system firmware is
> >  paired with the OS install (similar to what macOS does for itself)
> >  which prevents breaking other OS installs on the same disk.
> >
> >* It allows us to store a 2nd stage bootloader (m1n1+u-boot+dtb) on
> >  the EFI System Partition (ESP) such that it can be easily upgraded
> >  from within Linux without affecting other OS installs on the same
> >  disk.
> >
> >* It allows the use of the "native" boot picker to switch between
> >  OSes.
> >
> >The approach the Asahi team has taken is to pair the APFS partition
> >with the ESP by adding a proprty that contains the partition UUID to
> >the device tree.  The installer ships u-boot with a patched distro
> >boot script that looks at this device tree property, figures out what
> >the right ESP is and loads the EFI bootloader
> >(efi/boot/bootaarch64.efi) from that partition.
> >
> >This approach has some drawbacks:
> >
> >1. U-Boot will still consider the first ESP as *the* ESP, which means
> >   that the ubootefi.var file is still read from and written from the
> >   first ESP.
> >
> >2. The distro boot script modifications don't work if U-Boot's
> >   built-in efibootmgr is used.  This probably also affects Simon's
> >   bootstd stuff.
> >
> >So my idea is to have U-Boot recognize the device tree property and
> >use it when it determines what partition is *the* ESP.  A proof of
> >concept diff is attached below.  This probably needs a bit of
> >massaging as reading the device tree property in generic EFI code like
> >this is probably not acceptable.  A better approach might be to have a
> >function that can be called from board-specific code that sets the UUID.
> >
> >Thoughts?  Would such a feature be useful on other hardware platforms?
> 
> efi/boot/bootaarch64.efi is only a fallback if load options are not
> set up. Once the operating system has generated a load option it is
> not used anymore.

In theory yes.  But like 99% of the machines supported by U-Boot,
there is no runtime EFI variables support on the Apple machines.  So
the OS can't generate a load option and you'll end up always booting
from the efi/boot/bootarch64.efi fallback.

> The MacBooks only have one drive. Why would you want two ESPs on one drive?
> 
> Why can't the Asahi team use the current UEFI bootflow? We should
> avoid unneeded deviations. Can the current deviations be removed in
> Asahi Linux?
> 
> Best regards
> 
> Heinrich 
> 
> >
> >commit 088f5626d4347cef76ad5a54477944886efb005a
> >Author: Mark Kettenis <kettenis at openbsd.org>
> >Date:   Sun Sep 25 01:57:24 2022 +0200
> >
> >    HACK: Use designated ESP
> >    
> >    Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
> >
> >diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
> >index 7ea0334083..86b867d319 100644
> >--- a/lib/efi_loader/efi_disk.c
> >+++ b/lib/efi_loader/efi_disk.c
> >@@ -523,6 +523,27 @@ static efi_status_t efi_disk_add_dev(
> > 				  desc->devnum, part);
> > 		}
> > 	}
> >+
> >+	ofnode chosen_node;
> >+	const char *uuid = NULL;
> >+	chosen_node = ofnode_path("/chosen");
> >+	if (ofnode_valid(chosen_node)) {
> >+		uuid = ofnode_read_string(chosen_node,
> >+					  "asahi,efi-system-partition");
> >+	}
> >+
> >+	/* Store designated EFI system partition */
> >+	if (part && uuid && strcmp(uuid, part_info->uuid) == 0) {
> >+		if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) {
> >+			efi_system_partition.uclass_id = desc->uclass_id;
> >+			efi_system_partition.devnum = desc->devnum;
> >+			efi_system_partition.part = part;
> >+			EFI_PRINT("EFI system partition: %s %x:%x\n",
> >+				  blk_get_uclass_name(desc->uclass_id),
> >+				  desc->devnum, part);
> >+		}
> >+	}
> >+
> > 	return EFI_SUCCESS;
> > error:
> > 	efi_delete_handle(&diskobj->header);
> 


More information about the U-Boot mailing list