From eefa0a647d34aaa09ceeb1781d5d81a4994d8b6a Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 6 Jul 2017 10:14:03 +0100 Subject: [PATCH] EFI: find EFI system partition by legacy MBR partition type 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 Reviewed-by: Alexander Graf Signed-off-by: Alexander Graf --- 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 7ede15ec26..7aff73d6f8 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, -- 2.39.2