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:
co-authored by
Claude Opus 4.6
parent
013b724e02
commit
34a476d0a1
@@ -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
|
||||
|
||||
|
||||
+141
-107
@@ -1,173 +1,207 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Quick-iterate on boot branding without rebuilding the ISO.
|
||||
# Boot branding dev — iterate on GRUB theme, Plymouth, and installer visuals
|
||||
# without rebuilding the ISO. Patches an existing ISO and boots in QEMU.
|
||||
#
|
||||
# Usage:
|
||||
# ./dev-branding.sh <base-iso>
|
||||
# ./dev-branding.sh [path-to-iso]
|
||||
#
|
||||
# What it does:
|
||||
# 1. Regenerates GRUB background and Plymouth logo from Python scripts
|
||||
# 2. Extracts the existing ISO
|
||||
# 3. Swaps in updated branding files (theme, background, Plymouth)
|
||||
# 4. Repackages as a new ISO
|
||||
# 5. Boots it in QEMU for testing
|
||||
#
|
||||
# This takes ~10 seconds instead of 20 minutes.
|
||||
#
|
||||
# For design-only iteration (no QEMU boot):
|
||||
# python3 branding/generate-grub-background.py /tmp/grub-bg.png && open /tmp/grub-bg.png
|
||||
# If no ISO is found locally, downloads the latest from the build server.
|
||||
# Edit files in branding/, re-run, see changes in ~10 seconds.
|
||||
#
|
||||
|
||||
set -e
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ISO="${1:-}"
|
||||
|
||||
if [ -z "$ISO" ] || [ ! -f "$ISO" ]; then
|
||||
# Auto-detect latest dev ISO on Desktop
|
||||
ISO=$(ls -t ~/Desktop/archipelago-dev-*.iso 2>/dev/null | head -1)
|
||||
fi
|
||||
if [ -z "$ISO" ] || [ ! -f "$ISO" ]; then
|
||||
ISO=$(ls -t "$SCRIPT_DIR/results/archipelago-*.iso" 2>/dev/null | head -1)
|
||||
fi
|
||||
if [ -z "$ISO" ] || [ ! -f "$ISO" ]; then
|
||||
echo "No ISO found. Provide a path or place one on Desktop/results."
|
||||
echo "Usage: $0 <base-iso>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
WORK="/tmp/archipelago-dev-branding"
|
||||
PATCHED="$SCRIPT_DIR/results/archipelago-dev-patched.iso"
|
||||
CACHED_ISO="$SCRIPT_DIR/results/archipelago-dev-base.iso"
|
||||
DEV_SERVER="archipelago@192.168.1.228"
|
||||
SSH_KEY="$HOME/.ssh/archipelago-deploy"
|
||||
|
||||
echo "=== Archipelago Branding Dev ==="
|
||||
echo " Base ISO: $ISO"
|
||||
echo ""
|
||||
echo " Archipelago Boot Branding Dev"
|
||||
echo ""
|
||||
|
||||
# Step 1: Regenerate assets
|
||||
echo "[1/4] Generating assets..."
|
||||
python3 "$SCRIPT_DIR/branding/generate-grub-background.py" /tmp/grub-bg.png 2>/dev/null && \
|
||||
echo " GRUB background: OK" || echo " GRUB background: FAILED"
|
||||
python3 "$SCRIPT_DIR/branding/generate-plymouth-logo.py" /tmp/plymouth-logo.png 2>/dev/null && \
|
||||
echo " Plymouth logo: OK" || echo " Plymouth logo: FAILED"
|
||||
# --- Find or download an ISO ---
|
||||
ISO="${1:-}"
|
||||
|
||||
# Also show the background for quick visual check
|
||||
if command -v open >/dev/null 2>&1; then
|
||||
open /tmp/grub-bg.png 2>/dev/null &
|
||||
# Search locally
|
||||
if [ -z "$ISO" ] || [ ! -f "$ISO" ]; then
|
||||
for pattern in \
|
||||
"$HOME/Desktop/archipelago-dev-"*.iso \
|
||||
"$HOME/Desktop/archipelago-unbundled-"*.iso \
|
||||
"$HOME/Desktop/archipelago-"*.iso \
|
||||
"$SCRIPT_DIR/results/archipelago-dev-base.iso" \
|
||||
"$SCRIPT_DIR/results/archipelago-"*.iso; do
|
||||
found=$(ls -t $pattern 2>/dev/null | head -1)
|
||||
if [ -n "$found" ] && [ -f "$found" ]; then
|
||||
ISO="$found"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Step 2: Extract ISO
|
||||
echo "[2/4] Extracting ISO..."
|
||||
# Download from server if not found
|
||||
if [ -z "$ISO" ] || [ ! -f "$ISO" ]; then
|
||||
echo " No ISO found locally. Downloading latest from build server..."
|
||||
REMOTE_ISO=$(ssh -i "$SSH_KEY" "$DEV_SERVER" \
|
||||
"ls -t /var/lib/archipelago/filebrowser/Builds/archipelago-dev-*.iso 2>/dev/null | head -1" 2>/dev/null)
|
||||
if [ -z "$REMOTE_ISO" ]; then
|
||||
REMOTE_ISO=$(ssh -i "$SSH_KEY" "$DEV_SERVER" \
|
||||
"ls -t /var/lib/archipelago/filebrowser/Builds/archipelago-unbundled-*.iso 2>/dev/null | head -1" 2>/dev/null)
|
||||
fi
|
||||
if [ -n "$REMOTE_ISO" ]; then
|
||||
mkdir -p "$SCRIPT_DIR/results"
|
||||
echo " Downloading: $(basename "$REMOTE_ISO")..."
|
||||
scp -i "$SSH_KEY" "$DEV_SERVER:$REMOTE_ISO" "$CACHED_ISO"
|
||||
ISO="$CACHED_ISO"
|
||||
echo " Saved to: $ISO"
|
||||
else
|
||||
echo " No ISO on server either. Run a CI build first."
|
||||
echo " Or place an ISO on your Desktop."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo " Base ISO: $(basename "$ISO") ($(du -h "$ISO" | cut -f1))"
|
||||
echo ""
|
||||
|
||||
# --- Extract ISO ---
|
||||
echo " [1/3] Extracting ISO..."
|
||||
if [ -d "$WORK" ]; then
|
||||
chmod -R u+w "$WORK" 2>/dev/null || true
|
||||
fi
|
||||
rm -rf "$WORK"
|
||||
mkdir -p "$WORK"
|
||||
|
||||
xorriso -osirrox on -indev "$ISO" -extract / "$WORK" 2>/dev/null || {
|
||||
# Fallback: mount + copy
|
||||
echo " xorriso extraction failed, trying hdiutil..."
|
||||
MNT=$(mktemp -d)
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
hdiutil attach "$ISO" -mountpoint "$MNT" -readonly -nobrowse 2>/dev/null
|
||||
else
|
||||
sudo mount -o loop,ro "$ISO" "$MNT"
|
||||
fi
|
||||
hdiutil attach "$ISO" -mountpoint "$MNT" -readonly -nobrowse 2>/dev/null || {
|
||||
echo " Could not mount ISO. Is it corrupt?"
|
||||
exit 1
|
||||
}
|
||||
cp -a "$MNT"/* "$WORK/" 2>/dev/null || true
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
hdiutil detach "$MNT" 2>/dev/null
|
||||
else
|
||||
sudo umount "$MNT"
|
||||
fi
|
||||
hdiutil detach "$MNT" 2>/dev/null || true
|
||||
rmdir "$MNT" 2>/dev/null || true
|
||||
}
|
||||
# Ensure files are writable after extraction
|
||||
chmod -R u+w "$WORK" 2>/dev/null || true
|
||||
|
||||
# Step 3: Patch branding
|
||||
echo "[3/4] Patching branding..."
|
||||
# --- Patch branding ---
|
||||
echo " [2/3] Patching branding..."
|
||||
THEME_DST="$WORK/boot/grub/themes/archipelago"
|
||||
mkdir -p "$THEME_DST"
|
||||
|
||||
# GRUB theme
|
||||
cp "$SCRIPT_DIR/branding/grub-theme/theme.txt" "$THEME_DST/" 2>/dev/null && \
|
||||
echo " theme.txt: OK"
|
||||
cp /tmp/grub-bg.png "$THEME_DST/background.png" 2>/dev/null && \
|
||||
echo " background.png: OK"
|
||||
# GRUB theme.txt
|
||||
if [ -f "$SCRIPT_DIR/branding/grub-theme/theme.txt" ]; then
|
||||
cp "$SCRIPT_DIR/branding/grub-theme/theme.txt" "$THEME_DST/"
|
||||
echo " theme.txt"
|
||||
fi
|
||||
|
||||
# GRUB background — use static file from branding dir
|
||||
if [ -f "$SCRIPT_DIR/branding/grub-theme/background.png" ]; then
|
||||
cp "$SCRIPT_DIR/branding/grub-theme/background.png" "$THEME_DST/background.png"
|
||||
echo " background.png (static)"
|
||||
elif [ -f "$SCRIPT_DIR/branding/generate-grub-background.py" ]; then
|
||||
python3 "$SCRIPT_DIR/branding/generate-grub-background.py" "$THEME_DST/background.png" 2>/dev/null
|
||||
echo " background.png (generated)"
|
||||
fi
|
||||
|
||||
# Plymouth theme
|
||||
if [ -d "$WORK/archipelago/plymouth-theme" ]; then
|
||||
cp "$SCRIPT_DIR/branding/plymouth-theme/"* "$WORK/archipelago/plymouth-theme/" 2>/dev/null
|
||||
cp /tmp/plymouth-logo.png "$WORK/archipelago/plymouth-theme/logo.png" 2>/dev/null
|
||||
echo " Plymouth theme: OK"
|
||||
PLYMOUTH_DST="$WORK/archipelago/plymouth-theme"
|
||||
mkdir -p "$PLYMOUTH_DST"
|
||||
if [ -d "$SCRIPT_DIR/branding/plymouth-theme" ]; then
|
||||
cp "$SCRIPT_DIR/branding/plymouth-theme/"* "$PLYMOUTH_DST/" 2>/dev/null || true
|
||||
echo " plymouth theme"
|
||||
fi
|
||||
|
||||
# GRUB config (in case you edited it)
|
||||
if [ -f "$SCRIPT_DIR/branding/grub.cfg" ]; then
|
||||
cp "$SCRIPT_DIR/branding/grub.cfg" "$WORK/boot/grub/grub.cfg"
|
||||
echo " grub.cfg: OK (custom)"
|
||||
fi
|
||||
|
||||
# ISOLINUX config
|
||||
if [ -f "$SCRIPT_DIR/branding/isolinux.cfg" ]; then
|
||||
cp "$SCRIPT_DIR/branding/isolinux.cfg" "$WORK/isolinux/isolinux.cfg"
|
||||
echo " isolinux.cfg: OK (custom)"
|
||||
fi
|
||||
|
||||
# Step 4: Repackage ISO
|
||||
echo "[4/4] Repackaging ISO..."
|
||||
# --- Repackage ISO ---
|
||||
echo " [3/3] Repackaging ISO..."
|
||||
mkdir -p "$SCRIPT_DIR/results"
|
||||
|
||||
# Find isohdpfx.bin
|
||||
# Find isohdpfx.bin — project copy first, then system
|
||||
ISOHDPFX=""
|
||||
for p in "$WORK/isolinux/isohdpfx.bin" \
|
||||
for p in "$SCRIPT_DIR/branding/isohdpfx.bin" \
|
||||
"$WORK/isolinux/isohdpfx.bin" \
|
||||
/usr/lib/ISOLINUX/isohdpfx.bin \
|
||||
/usr/share/syslinux/isohdpfx.bin \
|
||||
/opt/homebrew/share/syslinux/isohdpfx.bin; do
|
||||
[ -f "$p" ] && ISOHDPFX="$p" && break
|
||||
done
|
||||
|
||||
# Check for EFI image
|
||||
EFI_IMG="$WORK/boot/grub/efi.img"
|
||||
if [ -z "$ISOHDPFX" ]; then
|
||||
echo " ERROR: No isohdpfx.bin found. Cannot create bootable ISO."
|
||||
echo " Preview only — open the background:"
|
||||
open "$THEME_DST/background.png" 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$ISOHDPFX" ] && [ -f "$EFI_IMG" ]; then
|
||||
EFI_IMG="$WORK/boot/grub/efi.img"
|
||||
if [ -f "$EFI_IMG" ]; then
|
||||
xorriso -as mkisofs -o "$PATCHED" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-iso-level 3 \
|
||||
-J -joliet-long -R \
|
||||
-iso-level 3 -J -joliet-long -R \
|
||||
-isohybrid-mbr "$ISOHDPFX" \
|
||||
-c isolinux/boot.cat \
|
||||
-b isolinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-eltorito-alt-boot \
|
||||
-e boot/grub/efi.img \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
-no-emul-boot -isohybrid-gpt-basdat \
|
||||
-partition_offset 16 \
|
||||
"$WORK" 2>/dev/null
|
||||
elif [ -n "$ISOHDPFX" ]; then
|
||||
else
|
||||
xorriso -as mkisofs -o "$PATCHED" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-iso-level 3 \
|
||||
-J -joliet-long -R \
|
||||
-iso-level 3 -J -joliet-long -R \
|
||||
-isohybrid-mbr "$ISOHDPFX" \
|
||||
-c isolinux/boot.cat \
|
||||
-b isolinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-partition_offset 16 \
|
||||
"$WORK" 2>/dev/null
|
||||
else
|
||||
echo "Cannot repackage: no isohdpfx.bin found."
|
||||
echo "Install xorriso and isolinux: brew install xorriso"
|
||||
echo ""
|
||||
echo "You can still preview the assets:"
|
||||
echo " open /tmp/grub-bg.png"
|
||||
echo " open /tmp/plymouth-logo.png"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Patched: $PATCHED ($(du -h "$PATCHED" | cut -f1))"
|
||||
echo ""
|
||||
|
||||
# --- Boot in QEMU ---
|
||||
if ! command -v qemu-system-x86_64 >/dev/null 2>&1; then
|
||||
echo " QEMU not found. Install: brew install qemu"
|
||||
echo " Opening background preview instead..."
|
||||
open "$THEME_DST/background.png" 2>/dev/null || true
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Patched ISO: $PATCHED ($(du -h "$PATCHED" | cut -f1))"
|
||||
echo " Booting in QEMU (BIOS mode — shows ISOLINUX menu)..."
|
||||
echo " Press Ctrl+C to stop."
|
||||
echo ""
|
||||
|
||||
# Auto-boot in QEMU if available
|
||||
if command -v qemu-system-x86_64 >/dev/null 2>&1; then
|
||||
read -p "Boot in QEMU? [Y/n] " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
exec "$SCRIPT_DIR/test-iso-qemu.sh" "$PATCHED" --bios
|
||||
fi
|
||||
else
|
||||
echo "Install QEMU to test: brew install qemu"
|
||||
# Create test disk (use separate disk from other QEMU instances)
|
||||
DISK="/tmp/archipelago-branding-test.qcow2"
|
||||
# Kill any leftover QEMU from previous branding test
|
||||
pkill -f "archipelago-branding-test" 2>/dev/null || true
|
||||
sleep 1
|
||||
if [ ! -f "$DISK" ]; then
|
||||
qemu-img create -f qcow2 "$DISK" 20G 2>/dev/null
|
||||
fi
|
||||
|
||||
# Boot with BIOS to see the ISOLINUX/GRUB menu
|
||||
qemu-system-x86_64 \
|
||||
-machine pc \
|
||||
-m 4G \
|
||||
-smp 2 \
|
||||
-boot d \
|
||||
-cdrom "$PATCHED" \
|
||||
-drive if=virtio,format=qcow2,file="$DISK" \
|
||||
-net nic,model=virtio -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::8100-:80 \
|
||||
-vga virtio \
|
||||
-display default \
|
||||
-serial file:/tmp/archipelago-qemu-serial.log
|
||||
|
||||
echo ""
|
||||
echo " QEMU stopped. Serial log: /tmp/archipelago-qemu-serial.log"
|
||||
echo " Re-run to test again after editing branding files."
|
||||
|
||||
Reference in New Issue
Block a user