universalisos/kernel/scripts/build_iso.sh
Fábio Coutada 62e8454f91 build: add UEFI ISO builder, test boot scripts, EIM config
- make-uefi-iso.sh: UEFI ISO image builder
- test_boot.S, test_boot.ld: test boot assembly and linker script
- eim_config.toml: EIM (External Interface Module) configuration
- edk2-ovmf RPM for UEFI firmware
- GAP_ANALYSIS_PIKEOS_PARITY.md: PikeOS parity gap analysis
2026-07-15 15:33:07 +01:00

246 lines
7 KiB
Bash
Executable file

#!/bin/bash
# UniversalisOS — Bootable ISO Builder for Dell XPS 15 9560
#
# Creates a UEFI-bootable ISO image with:
# - GRUB2 UEFI bootloader
# - UniversalisOS kernel (multiboot2)
# - OVMF firmware module
#
# Usage:
# ./scripts/build_iso.sh # default build
# ./scripts/build_iso.sh --output foo.iso # custom output path
#
# Prerequisites: grub2-mkrescue (or grub-mkrescue), xorriso, mtools
#
# Output: universalisos-xps15.iso (ready to flash with dd or Rufus)
#
# SPDX-License-Identifier: MIT
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
KERNEL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
# ---- Configurable paths ----
BUILD_DIR="${KERNEL_DIR}/build/x86_64/qemu-x86_64-virt"
KERNEL_ELF="${BUILD_DIR}/universalisos.elf"
OVMF_FD="${KERNEL_DIR}/src/arch/x86_64/ovmf/OVMF.fd"
OUTPUT="${KERNEL_DIR}/universalisos-xps15.iso"
WORKDIR="/tmp/uos-iso-build-$$"
# ---- Parse arguments ----
while [[ $# -gt 0 ]]; do
case "$1" in
--output) OUTPUT="$2"; shift 2 ;;
--kernel) KERNEL_ELF="$2"; shift 2 ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
echo "=============================================="
echo " UniversalisOS ISO Builder — Dell XPS 15 9560"
echo "=============================================="
echo " Kernel: ${KERNEL_ELF}"
echo " OVMF: ${OVMF_FD}"
echo " Output: ${OUTPUT}"
echo ""
# ---- Check prerequisites ----
GRUB_MKRESCUE=""
if command -v grub2-mkrescue &>/dev/null; then
GRUB_MKRESCUE="grub2-mkrescue"
elif command -v grub-mkrescue &>/dev/null; then
GRUB_MKRESCUE="grub-mkrescue"
else
echo "ERROR: grub-mkrescue not found."
echo " Install: sudo dnf install grub2-tools-extra xorriso mtools"
exit 1
fi
for tool in xorriso mtools; do
if ! command -v "$tool" &>/dev/null; then
echo "ERROR: $tool not found. Install with: sudo dnf install $tool"
exit 1
fi
done
# ---- Check kernel exists ----
if [ ! -f "$KERNEL_ELF" ]; then
echo "ERROR: Kernel ELF not found at ${KERNEL_ELF}"
echo "Build first: make ARCH=x86_64 PLATFORM=qemu-x86_64-virt"
exit 1
fi
# ---- Check OVMF ----
if [ ! -f "$OVMF_FD" ]; then
echo "WARNING: OVMF.fd not found at ${OVMF_FD}"
echo " The 'ovmf' module entry in GRUB will not work."
echo " You can still boot without it."
HAS_OVMF=0
else
HAS_OVMF=1
fi
# ---- Clean and create work directory ----
rm -rf "$WORKDIR"
mkdir -p "$WORKDIR/boot/grub"
mkdir -p "$WORKDIR/EFI/BOOT"
# ---- Copy kernel ----
echo "[1/4] Copying kernel ELF..."
cp "$KERNEL_ELF" "$WORKDIR/boot/universalisos.elf"
# ---- Copy OVMF ----
if [ "$HAS_OVMF" -eq 1 ]; then
echo "[2/4] Copying OVMF firmware..."
cp "$OVMF_FD" "$WORKDIR/boot/ovmf.fd"
else
echo "[2/4] Skipping OVMF (not found)..."
fi
# ---- Create GRUB config ----
echo "[3/4] Creating GRUB2 configuration..."
cat > "$WORKDIR/boot/grub/grub.cfg" << 'GRUBEOF'
# UniversalisOS GRUB2 UEFI Configuration
# Dell XPS 15 9560 Edition
#
# SPDX-License-Identifier: MIT
set timeout=5
set default=0
# Load required GRUB modules
insmod part_gpt
insmod part_msdos
insmod fat
insmod ext2
insmod iso9660
insmod multiboot2
insmod normal
insmod boot
# Color scheme
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
menuentry "UniversalisOS" {
multiboot2 /boot/universalisos.elf
module2 /boot/ovmf.fd ovmf
boot
}
menuentry "UniversalisOS (Safe Mode)" {
multiboot2 /boot/universalisos.elf safe
boot
}
menuentry "UniversalisOS (Debug, serial console)" {
multiboot2 /boot/universalisos.elf console=ttyS0,115200 debug=1
boot
}
GRUBEOF
# ---- Create ISO ----
echo "[4/4] Creating bootable ISO with ${GRUB_MKRESCUE}..."
"$GRUB_MKRESCUE" -o "$OUTPUT" "$WORKDIR" 2>/dev/null || {
echo ""
echo "grub-mkrescue failed. Trying xorriso directly..."
# First, try to find the GRUB EFI binary
GRUB_EFI=""
for dir in /usr/lib/grub/x86_64-efi /usr/lib/grub/x86_64-efi/monolithic; do
if [ -f "$dir/grub.efi" ]; then
GRUB_EFI="$dir/grub.efi"
break
fi
done
if [ -z "$GRUB_EFI" ]; then
echo "ERROR: Cannot find grub.efi for x86_64-efi"
echo " Install grub2-efi-x64-modules: sudo dnf install grub2-efi-x64-modules"
rm -rf "$WORKDIR"
exit 1
fi
# Copy GRUB EFI binary
cp "$GRUB_EFI" "$WORKDIR/EFI/BOOT/BOOTX64.EFI"
# Create El Torito EFI boot image
EFI_IMG="/tmp/efi-boot-$$.img"
dd if=/dev/zero of="$EFI_IMG" bs=1M count=4 2>/dev/null
mkfs.fat -F 12 "$EFI_IMG" 2>/dev/null || mkfs.fat "$EFI_IMG" 2>/dev/null
# Mount and copy files
MNT="/tmp/efi-mnt-$$"
mkdir -p "$MNT"
mount -o loop "$EFI_IMG" "$MNT" 2>/dev/null || {
# Use mcopy as fallback
mmd -i "$EFI_IMG" ::/EFI 2>/dev/null || true
mmd -i "$EFI_IMG" ::/EFI/BOOT 2>/dev/null || true
mcopy -i "$EFI_IMG" "$WORKDIR/EFI/BOOT/BOOTX64.EFI" ::/EFI/BOOT/ 2>/dev/null || true
mmd -i "$EFI_IMG" ::/boot 2>/dev/null || true
mmd -i "$EFI_IMG" ::/boot/grub 2>/dev/null || true
mcopy -i "$EFI_IMG" "$WORKDIR/boot/grub/grub.cfg" ::/boot/grub/ 2>/dev/null || true
mcopy -i "$EFI_IMG" "$WORKDIR/boot/universalisos.elf" ::/boot/ 2>/dev/null || true
if [ "$HAS_OVMF" -eq 1 ]; then
mcopy -i "$EFI_IMG" "$WORKDIR/boot/ovmf.fd" ::/boot/ 2>/dev/null || true
fi
}
if mountpoint -q "$MNT" 2>/dev/null; then
mkdir -p "$MNT/EFI/BOOT" "$MNT/boot/grub"
cp "$WORKDIR/EFI/BOOT/BOOTX64.EFI" "$MNT/EFI/BOOT/"
cp "$WORKDIR/boot/grub/grub.cfg" "$MNT/boot/grub/"
cp "$WORKDIR/boot/universalisos.elf" "$MNT/boot/"
[ "$HAS_OVMF" -eq 1 ] && cp "$WORKDIR/boot/ovmf.fd" "$MNT/boot/"
umount "$MNT"
fi
rmdir "$MNT" 2>/dev/null || true
# Create ISO with xorriso
xorriso -as mkisofs \
-R -J -joliet-long \
-eltorito-alt-boot \
-e "$EFI_IMG" \
-no-emul-boot \
-isohybrid-gpt-basdat \
-o "$OUTPUT" \
"$WORKDIR" 2>/dev/null || {
echo "ERROR: ISO creation failed."
rm -f "$EFI_IMG"
rm -rf "$WORKDIR"
exit 1
}
rm -f "$EFI_IMG"
}
# ---- Cleanup ----
rm -rf "$WORKDIR"
# ---- Report ----
echo ""
echo "=============================================="
echo " ISO Created Successfully!"
echo "=============================================="
echo " Output: ${OUTPUT}"
echo " Size: $(du -h "$OUTPUT" | cut -f1)"
echo ""
echo " Flash to USB:"
echo " sudo dd if=${OUTPUT} of=/dev/sdX bs=4M status=progress"
echo ""
echo " Test in QEMU (UEFI):"
echo " qemu-system-x86_64 \\"
echo " -bios /usr/share/OVMF/OVMF_CODE.fd \\"
echo " -cdrom ${OUTPUT} \\"
echo " -m 4096 -serial stdio -display none"
echo ""
echo " Test with NVMe emulation:"
echo " qemu-img create nvme.img 1G"
echo " qemu-system-x86_64 \\"
echo " -bios /usr/share/OVMF/OVMF_CODE.fd \\"
echo " -cdrom ${OUTPUT} \\"
echo " -drive file=nvme.img,if=none,id=nvme \\"
echo " -device nvme,serial=12345,drive=nvme \\"
echo " -m 4096 -serial stdio -display none"
echo "=============================================="