#!/bin/sh set -e _SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" HIPERISO_ROOT="$(cd "$_SCRIPT_DIR/.." && pwd)" GRUB2_INSTALL="$HIPERISO_ROOT/build/grub2-204/INSTALL" PAYLOAD="$HIPERISO_ROOT/build/payload" STAGING="$HIPERISO_ROOT/build/staging" _progress() { printf ' \033[1;34m[%d/8]\033[0m %s\n' "$1" "$2"; } # ── Dependency checks ───────────────────────────────────────────── command -v mcopy >/dev/null 2>&1 || { echo "ERROR: mtools (mmd/mcopy) required to build ESP image"; exit 1; } command -v mkfs.vfat >/dev/null 2>&1 || { echo "ERROR: dosfstools (mkfs.vfat) required"; exit 1; } GRUB_X64_DIR="$HIPERISO_ROOT/build/grub2-204/RUNTIME/grub/x86_64-efi" [ -d "$GRUB_X64_DIR" ] || GRUB_X64_DIR="$GRUB2_INSTALL/lib/grub/x86_64-efi" [ -d "$GRUB_X64_DIR" ] || GRUB_X64_DIR="$HIPERISO_ROOT/src/grub2/grub/x86_64-efi" KERNEL_SRC="$STAGING/efi/vmlinuz" [ -f "$KERNEL_SRC" ] || KERNEL_SRC="$STAGING/vmlinuz" EFI_BOOT_SRC="$HIPERISO_ROOT/grub2/bin/BOOTX64.EFI" [ -f "$EFI_BOOT_SRC" ] || EFI_BOOT_SRC="$STAGING/efi/BOOTX64.EFI" [ -f "$EFI_BOOT_SRC" ] || EFI_BOOT_SRC="$STAGING/EFI/BOOT/BOOTX64.EFI" REAL_GRUB_SRC="$HIPERISO_ROOT/grub2/bin/grubx64_real.efi" [ -f "$REAL_GRUB_SRC" ] || REAL_GRUB_SRC="$STAGING/efi/grubx64_real.efi" GRUB_EFI_ALIAS_SRC="$HIPERISO_ROOT/grub2/bin/grubx64.efi" [ -f "$GRUB_EFI_ALIAS_SRC" ] || GRUB_EFI_ALIAS_SRC="$STAGING/efi/grubx64.efi" SHIM_BOOT_SRC="$HIPERISO_ROOT/vendor/secureboot/BOOTX64.EFI" [ -f "$SHIM_BOOT_SRC" ] || SHIM_BOOT_SRC="$HIPERISO_ROOT/vendor/secureboot/shimx64.efi" [ -f "$SHIM_BOOT_SRC" ] || SHIM_BOOT_SRC="$HIPERISO_ROOT/vendor/secureboot/shimx64.efi.signed" # Clean only subdirectories this script fully repopulates. # Preserve tool/ (languages.json, HiperisoGTK.glade, GUI binaries) # and WebUI/plugson.www from build_gui_all.sh. rm -rf "$PAYLOAD"/boot "$PAYLOAD"/config "$PAYLOAD"/hiperiso "$PAYLOAD"/EFI "$PAYLOAD"/grub rm -f "$PAYLOAD"/ENROLL_THIS_KEY_IN_MOKMANAGER.cer mkdir -p "$PAYLOAD/boot" mkdir -p "$PAYLOAD/config" mkdir -p "$PAYLOAD/hiperiso" mkdir -p "$PAYLOAD/EFI/BOOT" mkdir -p "$PAYLOAD/EFI/hiperiso/trace" mkdir -p "$PAYLOAD/grub" mkdir -p "$PAYLOAD/tool/x86_64" _progress 1 "Copying boot images & EFI payloads..." # ── boot/ (BIOS boot images, vendored) ──────────────────────────── cp "$HIPERISO_ROOT/vendor/grub-i386-pc/boot.img" "$PAYLOAD/boot/boot.img" cp "$HIPERISO_ROOT/vendor/grub-i386-pc/core.img" "$PAYLOAD/boot/core.img" xz --check=crc32 "$PAYLOAD/boot/core.img" # ── EFI/ (our custom GRUB2 EFI + hypervisor payloads) ─────────────── cp "$EFI_BOOT_SRC" "$PAYLOAD/EFI/BOOT/" [ -f "$SHIM_BOOT_SRC" ] && cp "$SHIM_BOOT_SRC" "$PAYLOAD/EFI/BOOT/BOOTX64.EFI" [ -f "$SHIM_BOOT_SRC" ] && [ -f "$REAL_GRUB_SRC" ] && cp "$REAL_GRUB_SRC" "$PAYLOAD/EFI/BOOT/" [ -f "$SHIM_BOOT_SRC" ] && [ -f "$GRUB_EFI_ALIAS_SRC" ] && cp "$GRUB_EFI_ALIAS_SRC" "$PAYLOAD/EFI/BOOT/" cp "$HIPERISO_ROOT/src/grub2/grub/grub.cfg" "$PAYLOAD/EFI/BOOT/" [ -f "$SHIM_BOOT_SRC" ] && [ -f "$HIPERISO_ROOT/vendor/secureboot/mmx64.efi" ] && \ cp "$HIPERISO_ROOT/vendor/secureboot/mmx64.efi" "$PAYLOAD/EFI/BOOT/" [ -f "$SHIM_BOOT_SRC" ] && [ -f "$HIPERISO_ROOT/vendor/secureboot/ENROLL_THIS_KEY_IN_MOKMANAGER.cer" ] && \ cp "$HIPERISO_ROOT/vendor/secureboot/ENROLL_THIS_KEY_IN_MOKMANAGER.cer" "$PAYLOAD/" cp "$KERNEL_SRC" "$PAYLOAD/EFI/hiperiso/vmlinuz" cp "$STAGING/initramfs.cpio.gz" "$PAYLOAD/EFI/hiperiso/" cp "$STAGING/OVMF.fd" "$PAYLOAD/EFI/hiperiso/" cp "$STAGING/hiperiso-log" "$PAYLOAD/EFI/hiperiso/" cp "$HIPERISO_ROOT/logging/trace-"*.events "$PAYLOAD/EFI/hiperiso/trace/" _progress 2 "Copying GRUB2 configs, themes & modules..." # ── grub/ (configs, themes, modules from GRUB2 2.04 build) ────────── cp "$HIPERISO_ROOT/src/grub2/grub/grub.cfg" "$PAYLOAD/grub/" cp -a "$GRUB_X64_DIR" "$PAYLOAD/grub/x86_64-efi" mkdir -p "$PAYLOAD/grub/i386-pc" cp "$HIPERISO_ROOT/vendor/grub-i386-pc/"*.lst "$PAYLOAD/grub/i386-pc/" 2>/dev/null || true cp "$HIPERISO_ROOT/vendor/grub-i386-pc/"*.mod "$PAYLOAD/grub/i386-pc/" 2>/dev/null || true for cfg in checksum.cfg debug.cfg hwinfo.cfg keyboard.cfg localboot.cfg menulang.cfg power.cfg; do cp "$HIPERISO_ROOT/src/grub2/grub/$cfg" "$PAYLOAD/grub/" 2>/dev/null || true done for dir in distro help menu themes fonts; do cp -a "$HIPERISO_ROOT/src/grub2/grub/$dir" "$PAYLOAD/grub/" 2>/dev/null || true done if [ -d "$PAYLOAD/grub/help" ]; then tar -C "$PAYLOAD/grub" -czf "$PAYLOAD/grub/help.tar.gz" help fi if [ -d "$PAYLOAD/grub/menu" ]; then tar -C "$PAYLOAD/grub" -czf "$PAYLOAD/grub/menu.tar.gz" menu fi _progress 3 "Copying installer tools & scripts..." # ── tool/ (installer scripts + vendored assets + binary tools) ───── cp "$HIPERISO_ROOT/src/installer/tool/hiperiso_lib.sh" "$PAYLOAD/tool/" cp "$HIPERISO_ROOT/src/installer/tool/HiperisoWorker.sh" "$PAYLOAD/tool/" cp "$HIPERISO_ROOT/src/installer/tool/create_hiperiso_iso_part_dm.sh" "$PAYLOAD/tool/" cp "$HIPERISO_ROOT/assets/languages.json" "$PAYLOAD/tool/languages.json" cp "$HIPERISO_ROOT/assets/HiperisoGTK.glade" "$PAYLOAD/tool/HiperisoGTK.glade" [ -f "$HIPERISO_ROOT/vendor/secureboot/ENROLL_THIS_KEY_IN_MOKMANAGER.cer" ] && \ cp "$HIPERISO_ROOT/vendor/secureboot/ENROLL_THIS_KEY_IN_MOKMANAGER.cer" "$PAYLOAD/tool/" for tool in ash hexdump mkexfatfs mount.exfat-fuse xzcat; do cp "$HIPERISO_ROOT/vendor/tool-x86_64/$tool" "$PAYLOAD/tool/x86_64/" done [ -f "$PAYLOAD/tool/x86_64/Hiperiso2Disk.qt5" ] && chmod +x "$PAYLOAD/tool/x86_64/Hiperiso2Disk.qt5" [ -f "$PAYLOAD/tool/x86_64/Hiperiso2Disk.gtk3" ] && chmod +x "$PAYLOAD/tool/x86_64/Hiperiso2Disk.gtk3" # ── Top-level scripts ─────────────────────────────────────────────── for f in Hiperiso.sh HiperisoQt.sh HiperisoGtk.sh HiperisoWeb.sh HiperisoPlugson.sh \ Hiperiso2Disk.sh CreatePersistentImg.sh ExtendPersistentImg.sh hisocli hisolnk; do cp "$HIPERISO_ROOT/src/installer/$f" "$PAYLOAD/" chmod +x "$PAYLOAD/$f" done # ── config/ ───────────────────────────────────────────────────────── cp "$HIPERISO_ROOT/config/hiperiso.json.example" "$PAYLOAD/config/" # ── version ───────────────────────────────────────────────────────── echo "1.0.0" > "$PAYLOAD/hiperiso/version" _progress 4 "Extracting support files..." # Extract direct-boot support files if [ -f "$HIPERISO_ROOT/vendor/support-x64.tar.xz" ]; then tar -xJf "$HIPERISO_ROOT/vendor/support-x64.tar.xz" -C "$STAGING/" cp -a "$STAGING/support-x64/"* "$PAYLOAD/hiperiso/" fi # Copy Ventoy's runtime modules into the payload. The modsrc's GRUB # binary runs ventoy_check_official_device() at boot, which requires # `ventoy/ventoy.cpio` on the ESP. We vendor it under # `vendor/ventoy-runtime/` (sourced from upstream Ventoy 1.0.96, the # same version our modsrc is built from). Without this, the modsrc's # GRUB halts with "This is NOT a standard Ventoy device" before the # menu ever renders. mkdir -p "$PAYLOAD/hiperiso/ventoy" if [ -f "$HIPERISO_ROOT/vendor/ventoy-runtime/ventoy.cpio" ]; then cp "$HIPERISO_ROOT/vendor/ventoy-runtime/ventoy.cpio" \ "$PAYLOAD/hiperiso/ventoy/ventoy.cpio" fi rm -f "$PAYLOAD/log.txt" _progress 5 "Staging ESP content tree..." ESP_IMG="$PAYLOAD/hiperiso/hiperiso.disk.img" ESP_STAGING=$(mktemp -d) trap 'rm -rf "$ESP_STAGING"' EXIT INT TERM mkdir -p "$ESP_STAGING/EFI/BOOT" "$ESP_STAGING/EFI/hiperiso/trace" \ "$ESP_STAGING/grub" "$ESP_STAGING/tool" "$ESP_STAGING/hiperiso" cp "$PAYLOAD/EFI/BOOT/BOOTX64.EFI" "$PAYLOAD/EFI/BOOT/grub.cfg" "$ESP_STAGING/EFI/BOOT/" [ -f "$PAYLOAD/EFI/BOOT/grubx64_real.efi" ] && cp "$PAYLOAD/EFI/BOOT/grubx64_real.efi" "$ESP_STAGING/EFI/BOOT/" [ -f "$PAYLOAD/EFI/BOOT/grubx64.efi" ] && cp "$PAYLOAD/EFI/BOOT/grubx64.efi" "$ESP_STAGING/EFI/BOOT/" [ -f "$PAYLOAD/EFI/BOOT/mmx64.efi" ] && cp "$PAYLOAD/EFI/BOOT/mmx64.efi" "$ESP_STAGING/EFI/BOOT/" [ -f "$PAYLOAD/ENROLL_THIS_KEY_IN_MOKMANAGER.cer" ] && cp "$PAYLOAD/ENROLL_THIS_KEY_IN_MOKMANAGER.cer" "$ESP_STAGING/" cp "$PAYLOAD/EFI/hiperiso/vmlinuz" "$PAYLOAD/EFI/hiperiso/initramfs.cpio.gz" \ "$PAYLOAD/EFI/hiperiso/OVMF.fd" "$PAYLOAD/EFI/hiperiso/hiperiso-log" "$ESP_STAGING/EFI/hiperiso/" cp "$PAYLOAD"/EFI/hiperiso/trace/*.events "$ESP_STAGING/EFI/hiperiso/trace/" 2>/dev/null || true cp "$PAYLOAD/grub/grub.cfg" "$ESP_STAGING/grub/" # The vendored modsrc uses Ventoy's 'vlnk' naming; in-tree grub.cfg # uses rebrand 'hlnk'. Rewrite the deployed config to match the binary. if [ -f "$ESP_STAGING/grub/grub.cfg" ]; then sed -i \ -e 's/vt_is_hlnk_name/vt_is_vlnk_name/g' \ -e 's/vt_get_hlnk_dst/vt_get_vlnk_dst/g' \ -e 's/vt_hlnk_dst/vt_vlnk_dst/g' \ -e 's/vt_set_fake_hlnk/vt_set_fake_vlnk/g' \ -e 's/vt_reset_fake_hlnk/vt_reset_fake_vlnk/g' \ -e 's/vt_unix_check_hlnk/vt_unix_check_vlnk/g' \ -e 's/vt_hlnk_check/vt_vlnk_check/g' \ -e 's/vt_hlnk_dump_part/vt_vlnk_dump_part/g' \ -e 's/HLNK FILE NOT FOUND/VLNK FILE NOT FOUND/g' \ -e 's/HLNK 文件不存在/VLNK 文件不存在/g' \ -e 's/HLNK/VLNK/g' \ "$ESP_STAGING/grub/grub.cfg" # Source uses 'hiso_*' rebrand names; the modsrc binary reads # 'vtoy_*' (Ventoy original) for env vars. Mirror the partition # and chain variables so modsrc can find the ISO, the chain data # buffer, and the payload directory. Two patterns per name: one # for the bare $var form, one for the ${var} brace form. sed -i \ -e 's/{hiso_/{vtoy_/g' \ -e 's/\$hiso_/\$vtoy_/g' \ "$ESP_STAGING/grub/grub.cfg" fi # Copy chain-boot EFI binaries + helpers to the ESP at /hiperiso/ # (grub.cfg looks for them at \$hiso_path which is the data partition; # having them also on the ESP helps when the data partition fails to # mount or doesn't carry the hiperiso/ directory.) mkdir -p "$ESP_STAGING/hiperiso" for efi in hiperiso_x64.efi iso9660_x64.efi udf_x64.efi vtoyutil_x64.efi wimboot.x86_64.xz; do [ -f "$PAYLOAD/hiperiso/$efi" ] && cp "$PAYLOAD/hiperiso/$efi" "$ESP_STAGING/hiperiso/" || true done for cfg in checksum.cfg debug.cfg hwinfo.cfg keyboard.cfg localboot.cfg menulang.cfg power.cfg; do [ -f "$PAYLOAD/grub/$cfg" ] && cp "$PAYLOAD/grub/$cfg" "$ESP_STAGING/grub/" || true done [ -f "$PAYLOAD/grub/help.tar.gz" ] && cp "$PAYLOAD/grub/help.tar.gz" "$ESP_STAGING/grub/" [ -f "$PAYLOAD/grub/menu.tar.gz" ] && cp "$PAYLOAD/grub/menu.tar.gz" "$ESP_STAGING/grub/" for dir in themes fonts distro help menu x86_64-efi i386-pc; do [ -d "$PAYLOAD/grub/$dir" ] && cp -a "$PAYLOAD/grub/$dir" "$ESP_STAGING/grub/" || true done find "$ESP_STAGING/grub" -name '*.module' -delete 2>/dev/null || true find "$ESP_STAGING/grub" -name '*.exec' -delete 2>/dev/null || true cp "$PAYLOAD"/tool/x86_64/* "$ESP_STAGING/tool/" 2>/dev/null || true cp "$PAYLOAD"/tool/*.sh "$PAYLOAD"/tool/*.json "$PAYLOAD"/tool/*.glade "$PAYLOAD"/tool/*.cer \ "$ESP_STAGING/tool/" 2>/dev/null || true cp "$PAYLOAD/hiperiso/version" "$ESP_STAGING/hiperiso/" for f in "$PAYLOAD"/hiperiso/*; do [ -f "$f" ] || continue case "$(basename "$f")" in hiperiso.disk.img*) continue ;; esac cp "$f" "$ESP_STAGING/hiperiso/" done for d in 7z imdisk; do [ -d "$PAYLOAD/hiperiso/$d" ] && cp -a "$PAYLOAD/hiperiso/$d" "$ESP_STAGING/hiperiso/" || true done # Stage ventoy/ at the ESP root. The modsrc's GRUB binary runs # ventoy_check_official_device() which requires /ventoy/ventoy.cpio # to be at the partition root (not under hiperiso/). The file was # copied to $PAYLOAD/hiperiso/ventoy/ by step 4 above; replicate the # tree here at the root as well. if [ -d "$PAYLOAD/hiperiso/ventoy" ]; then cp -a "$PAYLOAD/hiperiso/ventoy" "$ESP_STAGING/" fi _progress 6 "Creating 32MB FAT16 ESP image ($(find "$ESP_STAGING" -type f | wc -l) files, $(du -sh "$ESP_STAGING" | cut -f1))..." dd if=/dev/zero of="$ESP_IMG" bs=1M count=32 2>/dev/null # FAT16 volume label MUST be "VTOYEFI" (modsrc's GRUB hardcodes # this check at ventoy_check_official_device). Using "HISOEFI" here # would fail with error 10 "Partition name is not VTOYEFI". mkfs.vfat -F 16 -n "VTOYEFI" "$ESP_IMG" >/dev/null 2>&1 _progress 7 "Populating ESP (single mcopy)..." # mcopy with a wildcard of subdirs + ::/ does not recurse reliably # in all mtools versions. Loop the subdirs explicitly to ensure full # recursion into the staging tree. for entry in "$ESP_STAGING"/*; do name=$(basename "$entry") if [ -d "$entry" ]; then mcopy -s -i "$ESP_IMG" "$entry" "::/$name" 2>/dev/null || true elif [ -f "$entry" ]; then mcopy -i "$ESP_IMG" "$entry" "::/$name" 2>/dev/null || true fi done rm -rf "$ESP_STAGING" trap - EXIT INT TERM _progress 8 "Compressing ESP image ($(du -h "$ESP_IMG" | cut -f1))..." xz --check=crc32 "$ESP_IMG" echo "=== hiperiso release package assembled ===" du -sh "$PAYLOAD" find "$PAYLOAD" -type f | wc -l echo "files"