iso: a real EFI system partition, so a stick boots on strict firmware

-isohybrid-gpt-basdat does nothing without an MBR template, so the ISO
had no partition table at all: written to a stick, it was a CD
filesystem at sector 0. AMI on a B550 (and OVMF) read El Torito off any
block device and booted it anyway. An HP all-in-one from 2012 looks for
an EFI system partition on a USB disk, as the spec says to, found none,
and listed the stick under Legacy only.

The FAT image now goes in a second time as MBR partition 2, type 0xEF,
and is FAT16 by cluster count rather than FAT12, the type old firmware
reads worst. Booted under OVMF both as a CD and as a USB disk. The ISO
also rebuilds when mkiso.sh changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-23 16:19:27 +02:00
commit 125663929a
2 changed files with 20 additions and 4 deletions

View file

@ -758,7 +758,7 @@ iso:
# One El Torito entry, pointing at a FAT image holding the loader and kernel.
# sysroot-install because the disc also carries the tree as a real hierarchy.
schos.iso: $(BUILD)/kernel/kernel $(BUILD)/uefi/BOOTX64.EFI sysroot-install
schos.iso: $(BUILD)/kernel/kernel $(BUILD)/uefi/BOOTX64.EFI tools/posix/mkiso.sh sysroot-install
SYSROOT=$(SYSROOT) sh tools/posix/mkiso.sh $@
# A partitioned disk -- GPT, an ESP and a SchFS partition -- which is what a

View file

@ -121,7 +121,13 @@ cp "$KERNEL" "$STAGING/schos/kernel"
EFI_IMG="$STAGING/boot/efiboot.img"
payload_kb=$(( ( $(wc -c < "$EFIAPP") + $(wc -c < "$KERNEL") + 1023 ) / 1024 ))
img_kb=$(( ( (payload_kb + 512 + 31) / 32 ) * 32 ))
[ "$img_kb" -lt 512 ] && img_kb=512
# FAT16, chosen by cluster count: a firmware decides FAT12/16/32 from the
# number of clusters alone, as the spec says to, and FAT12 is the type older
# firmware is least likely to read on a removable disk. So at least 8 MB, and
# the smallest power-of-two cluster that keeps the count under FAT16's 65525.
[ "$img_kb" -lt 8192 ] && img_kb=8192
spc=1
while [ $(( img_kb * 2 / spc )) -gt 65000 ]; do spc=$(( spc * 2 )); done
rm -f "$EFI_IMG"
if true; then
@ -133,7 +139,7 @@ if true; then
# image be whatever the loader actually needs, which is the point of sizing
# it from the file rather than hardcoding 1.44 MB.
dd if=/dev/zero of="$EFI_IMG" bs=1024 count="$img_kb" status=none
mformat -i "$EFI_IMG" -h 64 -s 32 -T $((img_kb * 2)) ::
mformat -i "$EFI_IMG" -h 64 -s 32 -c $spc -T $((img_kb * 2)) ::
mmd -i "$EFI_IMG" ::/EFI ::/EFI/BOOT ::/schos
mcopy -i "$EFI_IMG" "$EFIAPP" ::/EFI/BOOT/BOOTX64.EFI
mcopy -i "$EFI_IMG" "$KERNEL" ::/schos/kernel
@ -156,7 +162,17 @@ fi
# mkisofs.exe.
if command -v xorriso >/dev/null 2>&1; then
MKISOFS="xorriso -as mkisofs"
HYBRID="-isohybrid-gpt-basdat" # mkisofs proper does not know this one
# The same FAT image again, as a partition of its own in an MBR.
#
# This used to be -isohybrid-gpt-basdat, which does nothing without an
# MBR template (-isohybrid-mbr) -- so the ISO had no partition table at
# all, and written to a stick it was a CD filesystem at sector 0. A
# B550's firmware reads that as though it were a disc and boots it; an
# HP all-in-one from 2012 looks for an EFI system partition on a USB
# disk, finds none, and lists the stick under Legacy only. A partition
# of type 0xEF is what every UEFI firmware looks for on a removable
# disk, MBR rather than GPT because the oldest ones read that best.
HYBRID="-append_partition 2 0xef $EFI_IMG"
elif command -v mkisofs >/dev/null 2>&1; then
MKISOFS="mkisofs"
HYBRID=""