[U-Boot] [PATCH] EFI: find EFI system partition by legacy MBR partition type

Alexander Graf
2017-07-06T09:23:35Z

On 07/06/2017 11:14 AM, Andre Przywara wrote:
> The UEFI spec allows an EFI system partition (ESP, with the bootloader or
> kernel EFI apps on it) to reside on a disk using a "legacy" MBR
> partitioning scheme.
> But in contrast to actual legacy disks the ESP is not marked as
> "bootable" using bit 7 in byte 0 of the legacy partition entry, but is
> instead using partition *type* 0xef (in contrast to 0x0b or 0x0c for a
> normal FAT partition). The EFI spec isn't 100% clear on this, but it even
> seems to discourage the use of the bootable flag for ESPs.
> Also it seems that some EFI implementations (EDK2?) even seem to ignore
> partitions marked as bootable (probably since they believe they contain
> legacy boot code).
> The Debian installer [1] (*not* mini.iso), for instance, contains such an
> MBR, where none of the two partitions are marked bootable, but the ESP
> has clearly type 0xef.
> Now U-Boot cannot find the ESP on such a disk (USB flash drive) and
> fails to load the EFI grub and thus the installer.
>
> Since it all boils down to the distro bootcmds eventually calling
> "part list -bootable" to find potential boot partitions, it seems logical
> to just add this "partition type is 0xef" condition to the is_bootable()
> implementation.
>
> This allows the bog standard arm64 Debian-testing installer to boot from
> an USB pen drive on Allwinner A64 boards (Pine64, BananaPi-M64).
> (Ubuntu and other distribution installers don't have a legacy MBR, so
> U-Boot falls back to El Torito there).
>
> [1] https://cdimage.debian.org/cdimage/daily-builds/daily/arch-latest/arm64/iso-cd/
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>

I think this change is perfectly reasonable, yes.

Reviewed-by: Alexander Graf <agraf@suse.de>

Alex

> ---
> disk/part_dos.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/disk/part_dos.c b/disk/part_dos.c
> index 7ede15e..7aff73d 100644
> --- a/disk/part_dos.c
> +++ b/disk/part_dos.c
> @@ -44,7 +44,7 @@ static inline int is_extended(int part_type)
>
> static inline int is_bootable(dos_partition_t *p)
> {
> - return p->boot_ind == 0x80;
> + return (p->sys_ind == 0xef) || (p->boot_ind == 0x80);
> }
>
> static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,