From 125663929a0a4d029101487875b99b0c02f2a5a7 Mon Sep 17 00:00:00 2001 From: Nexoniarz Date: Fri, 23 Oct 2026 16:19:27 +0200 Subject: [PATCH] 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 Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4 --- Makefile | 2 +- tools/posix/mkiso.sh | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index d35058d..36f3828 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/tools/posix/mkiso.sh b/tools/posix/mkiso.sh index 613c852..4cf408a 100644 --- a/tools/posix/mkiso.sh +++ b/tools/posix/mkiso.sh @@ -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=""