fix: xorriso append_partition for real USB boot + grub-mkstandalone
Root cause of USB boot failure: our xorriso used -e boot/grub/efi.img to embed the EFI image inside the ISO. This works for CD-ROM and QEMU but NOT for USB on real UEFI hardware. Fix: use the Will Haley / Debian live-build approach: - -append_partition 2 (GPT type EFI) appends efi.img AFTER ISO data - -e --interval:appended_partition_2:all:: references the appended partition - --mbr-force-bootable forces MBR active flag - grub-mkstandalone with embedded bootstrap config (searches for grub.cfg) - grub.cfg placed in both /boot/grub/ AND /EFI/BOOT/ on ISO - grub.cfg uses search --label ARCHIPELAGO to find the ISO root This is the exact approach used by StartOS, TAILS, and every production custom Debian live ISO that boots from USB. Also: iso-debug, iso-branding skills + reference docs, dev-start.sh option 0 for branding dev, improved dev-branding.sh and test-iso-qemu.sh. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -637,16 +637,25 @@ umount /installer/proc 2>/dev/null || true
|
||||
echo " [container] Creating installer squashfs..."
|
||||
mksquashfs /installer /output/filesystem.squashfs -comp xz -Xbcj x86 -noappend -quiet
|
||||
|
||||
# Build GRUB EFI image
|
||||
# Build GRUB EFI image with embedded bootstrap config (grub-mkstandalone)
|
||||
# This ensures GRUB can find its config on real hardware, not just QEMU
|
||||
echo " [container] Building GRUB EFI image..."
|
||||
grub-mkimage -O x86_64-efi -o /output/BOOTX64.EFI -p /boot/grub \
|
||||
part_gpt part_msdos fat iso9660 udf normal boot linux search \
|
||||
search_fs_uuid search_fs_file search_label configfile echo cat \
|
||||
ls test true loopback gfxterm gfxmenu font png all_video video \
|
||||
video_bochs video_cirrus efi_gop efi_uga
|
||||
cat > /tmp/grub-embed.cfg <<GRUBEMBED
|
||||
search --no-floppy --set=root --label ARCHIPELAGO
|
||||
set prefix=(\\\$root)/boot/grub
|
||||
configfile \\\$prefix/grub.cfg
|
||||
GRUBEMBED
|
||||
|
||||
# Create EFI FAT image (4MB)
|
||||
dd if=/dev/zero of=/output/efi.img bs=1M count=4 2>/dev/null
|
||||
grub-mkstandalone -O x86_64-efi \
|
||||
--modules="part_gpt part_msdos fat iso9660 all_video font gfxterm" \
|
||||
--locales="" \
|
||||
--themes="" \
|
||||
--fonts="" \
|
||||
--output=/output/BOOTX64.EFI \
|
||||
"boot/grub/grub.cfg=/tmp/grub-embed.cfg"
|
||||
|
||||
# Create EFI FAT image (20MB — includes GRUB binary + grub.cfg)
|
||||
dd if=/dev/zero of=/output/efi.img bs=1M count=20 2>/dev/null
|
||||
mkfs.vfat /output/efi.img >/dev/null
|
||||
mmd -i /output/efi.img ::/EFI ::/EFI/BOOT
|
||||
mcopy -i /output/efi.img /output/BOOTX64.EFI ::/EFI/BOOT/BOOTX64.EFI
|
||||
@@ -683,7 +692,7 @@ cp "$WORK_DIR/vmlinuz" "$INSTALLER_ISO/live/vmlinuz"
|
||||
cp "$WORK_DIR/initrd.img" "$INSTALLER_ISO/live/initrd.img"
|
||||
cp "$WORK_DIR/filesystem.squashfs" "$INSTALLER_ISO/live/filesystem.squashfs"
|
||||
cp "$WORK_DIR/BOOTX64.EFI" "$INSTALLER_ISO/EFI/BOOT/BOOTX64.EFI"
|
||||
cp "$WORK_DIR/efi.img" "$INSTALLER_ISO/boot/grub/efi.img"
|
||||
# Note: efi.img stays in $WORK_DIR — it gets appended as GPT partition 2 by xorriso
|
||||
cp "$WORK_DIR/isolinux.bin" "$INSTALLER_ISO/isolinux/isolinux.bin"
|
||||
cp "$WORK_DIR/ldlinux.c32" "$INSTALLER_ISO/isolinux/ldlinux.c32"
|
||||
cp "$WORK_DIR/menu.c32" "$INSTALLER_ISO/isolinux/menu.c32" 2>/dev/null || true
|
||||
@@ -2501,11 +2510,19 @@ echo "Step 5: Configuring boot loaders..."
|
||||
# Create GRUB configuration
|
||||
echo " Writing GRUB config..."
|
||||
cat > "$INSTALLER_ISO/boot/grub/grub.cfg" <<'GRUBCFG'
|
||||
insmod part_gpt
|
||||
insmod part_msdos
|
||||
insmod fat
|
||||
insmod iso9660
|
||||
insmod all_video
|
||||
|
||||
search --no-floppy --set=root --label ARCHIPELAGO
|
||||
|
||||
set timeout=5
|
||||
set default=0
|
||||
|
||||
# Load font for graphical menu
|
||||
if loadfont /boot/grub/font.pf2; then
|
||||
if loadfont ($root)/boot/grub/font.pf2; then
|
||||
set gfxmode=auto
|
||||
insmod gfxterm
|
||||
insmod png
|
||||
@@ -2513,26 +2530,25 @@ if loadfont /boot/grub/font.pf2; then
|
||||
fi
|
||||
|
||||
# Archipelago GRUB theme
|
||||
if [ -f /boot/grub/themes/archipelago/theme.txt ]; then
|
||||
# Load theme fonts
|
||||
loadfont /boot/grub/themes/archipelago/dejavu_12.pf2
|
||||
loadfont /boot/grub/themes/archipelago/dejavu_14.pf2
|
||||
loadfont /boot/grub/themes/archipelago/dejavu_16.pf2
|
||||
loadfont /boot/grub/themes/archipelago/dejavu_24.pf2
|
||||
set theme=/boot/grub/themes/archipelago/theme.txt
|
||||
if [ -f ($root)/boot/grub/themes/archipelago/theme.txt ]; then
|
||||
loadfont ($root)/boot/grub/themes/archipelago/dejavu_12.pf2
|
||||
loadfont ($root)/boot/grub/themes/archipelago/dejavu_14.pf2
|
||||
loadfont ($root)/boot/grub/themes/archipelago/dejavu_16.pf2
|
||||
loadfont ($root)/boot/grub/themes/archipelago/dejavu_24.pf2
|
||||
set theme=($root)/boot/grub/themes/archipelago/theme.txt
|
||||
else
|
||||
set menu_color_normal=light-gray/black
|
||||
set menu_color_highlight=white/dark-gray
|
||||
fi
|
||||
|
||||
menuentry "Install Archipelago" --hotkey=i {
|
||||
linux /live/vmlinuz boot=live components quiet console=ttyS0,115200 console=tty0
|
||||
initrd /live/initrd.img
|
||||
linux ($root)/live/vmlinuz boot=live components quiet console=ttyS0,115200 console=tty0
|
||||
initrd ($root)/live/initrd.img
|
||||
}
|
||||
|
||||
menuentry "Install Archipelago (verbose)" --hotkey=v {
|
||||
linux /live/vmlinuz boot=live components
|
||||
initrd /live/initrd.img
|
||||
linux ($root)/live/vmlinuz boot=live components console=ttyS0,115200 console=tty0
|
||||
initrd ($root)/live/initrd.img
|
||||
}
|
||||
|
||||
menuentry "Boot from local disk" --hotkey=b {
|
||||
@@ -2541,6 +2557,14 @@ menuentry "Boot from local disk" --hotkey=b {
|
||||
}
|
||||
GRUBCFG
|
||||
|
||||
# Copy grub.cfg to EFI/BOOT on ISO filesystem AND into the FAT EFI image
|
||||
# The embedded grub bootstrap does configfile "${cmdpath}/grub.cfg"
|
||||
cp "$INSTALLER_ISO/boot/grub/grub.cfg" "$INSTALLER_ISO/EFI/BOOT/grub.cfg"
|
||||
if [ -f "$WORK_DIR/efi.img" ]; then
|
||||
mcopy -oi "$WORK_DIR/efi.img" "$INSTALLER_ISO/boot/grub/grub.cfg" ::/EFI/BOOT/grub.cfg 2>/dev/null || \
|
||||
echo " WARNING: Could not copy grub.cfg into efi.img (mtools required)"
|
||||
fi
|
||||
|
||||
# Create ISOLINUX configuration (legacy BIOS boot)
|
||||
echo " Writing ISOLINUX config..."
|
||||
cat > "$INSTALLER_ISO/isolinux/isolinux.cfg" <<'ISOCFG'
|
||||
@@ -2607,35 +2631,44 @@ if [ ! -f "$ISOHDPFX" ]; then
|
||||
done
|
||||
fi
|
||||
|
||||
# EFI boot image was built in Step 2
|
||||
EFI_IMG="$INSTALLER_ISO/boot/grub/efi.img"
|
||||
# EFI boot image was built in Step 2 and placed at staging/efiboot.img
|
||||
# The Will Haley / Debian live-build approach: append EFI as GPT partition 2
|
||||
# This is what makes USB boot work on real UEFI hardware (not just QEMU)
|
||||
EFIBOOT="$WORK_DIR/efi.img"
|
||||
|
||||
if [ ! -f "$EFI_IMG" ]; then
|
||||
if [ ! -f "$EFIBOOT" ]; then
|
||||
echo " WARNING: No EFI boot image — ISO will only support Legacy BIOS boot"
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-iso-level 3 \
|
||||
-J -joliet-long -R \
|
||||
-full-iso9660-filenames \
|
||||
--mbr-force-bootable -partition_offset 16 \
|
||||
-joliet -joliet-long -rational-rock \
|
||||
-isohybrid-mbr "$ISOHDPFX" \
|
||||
-c isolinux/boot.cat \
|
||||
-b isolinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-partition_offset 16 \
|
||||
-eltorito-boot isolinux/isolinux.bin \
|
||||
-no-emul-boot \
|
||||
-boot-load-size 4 \
|
||||
-boot-info-table \
|
||||
--eltorito-catalog isolinux/isolinux.cat \
|
||||
"$INSTALLER_ISO"
|
||||
else
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-iso-level 3 \
|
||||
-J -joliet-long -R \
|
||||
-full-iso9660-filenames \
|
||||
--mbr-force-bootable -partition_offset 16 \
|
||||
-joliet -joliet-long -rational-rock \
|
||||
-isohybrid-mbr "$ISOHDPFX" \
|
||||
-c isolinux/boot.cat \
|
||||
-b isolinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-eltorito-boot isolinux/isolinux.bin \
|
||||
-no-emul-boot \
|
||||
-boot-load-size 4 \
|
||||
-boot-info-table \
|
||||
--eltorito-catalog isolinux/isolinux.cat \
|
||||
-eltorito-alt-boot \
|
||||
-e boot/grub/efi.img \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
-partition_offset 16 \
|
||||
-e --interval:appended_partition_2:all:: \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
-append_partition 2 C12A7328-F81F-11D2-BA4B-00A0C93EC93B "$EFIBOOT" \
|
||||
"$INSTALLER_ISO"
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user