#!/bin/zsh # vm_create.sh — Create a new vphone VM directory with all required files. # # Mirrors the vrevm VM creation process: # 1. Create VM directory structure # 2. Create sparse disk image (default 64 GB) # 3. Create SEP storage (512 KB flat file) # 4. Copy AVPBooter and AVPSEPBooter ROMs # 5. Generate config.plist manifest # # machineIdentifier and NVRAM are auto-created on first boot by vphone-cli. # # Usage: # make vm_new # Create VM/ with framework ROMs # make vm_new VM_DIR=MyVM # Custom directory name # make vm_new DISK_SIZE=32 # 32 GB disk set -euo pipefail # --- Defaults --- VM_DIR="${VM_DIR:-vm}" DISK_SIZE_GB="${DISK_SIZE:-64}" CPU_COUNT="${CPU:-8}" MEMORY_MB="${MEMORY:-8192}" SEP_STORAGE_SIZE=$((512 * 1024)) # 512 KB (same as vrevm) # Script directory SCRIPT_DIR="${0:A:h}" # Framework-bundled ROMs (vresearch1 / research1 chip) FW_ROM_DIR="/System/Library/Frameworks/Virtualization.framework/Versions/A/Resources" ROM_SRC="${FW_ROM_DIR}/AVPBooter.vresearch1.bin" SEPROM_SRC="${FW_ROM_DIR}/AVPSEPBooter.vresearch1.bin" # --- Parse args --- while [[ $# -gt 0 ]]; do case "$1" in --dir) VM_DIR="$2" shift 2 ;; --disk-size) DISK_SIZE_GB="$2" shift 2 ;; --rom) ROM_SRC="$2" shift 2 ;; --seprom) SEPROM_SRC="$2" shift 2 ;; -h | --help) echo "Usage: $0 [--dir VM] [--disk-size 64] [--rom path] [--seprom path]" echo "" echo "Options:" echo " --dir VM directory name (default: VM)" echo " --disk-size Disk image size in GB (default: 64)" echo " --rom Path to AVPBooter ROM (default: framework built-in)" echo " --seprom Path to AVPSEPBooter ROM (default: framework built-in)" exit 0 ;; *) echo "Unknown option: $1" exit 1 ;; esac done DISK_SIZE_BYTES=$((DISK_SIZE_GB * 1024 * 1024 * 1024)) echo "=== vphone create_vm ===" echo "Directory : ${VM_DIR}" echo "Disk size : ${DISK_SIZE_GB} GB" echo "AVPBooter : ${ROM_SRC}" echo "AVPSEPBooter: ${SEPROM_SRC}" echo "" # --- Validate ROM sources --- if [[ ! -f "${ROM_SRC}" ]]; then echo "ERROR: AVPBooter ROM not found: ${ROM_SRC}" echo " On Apple Internal macOS, this should be at:" echo " ${FW_ROM_DIR}/AVPBooter.vresearch1.bin" exit 1 fi if [[ ! -f "${SEPROM_SRC}" ]]; then echo "ERROR: AVPSEPBooter ROM not found: ${SEPROM_SRC}" echo " On Apple Internal macOS, this should be at:" echo " ${FW_ROM_DIR}/AVPSEPBooter.vresearch1.bin" exit 1 fi # --- Create VM directory --- if [[ -d "${VM_DIR}" ]]; then echo "WARNING: ${VM_DIR}/ already exists" # Check for existing disk to avoid accidental overwrite if [[ -f "${VM_DIR}/Disk.img" ]]; then echo " Disk.img already exists — skipping disk creation" echo " Delete ${VM_DIR}/Disk.img manually to recreate" fi else echo "[1/4] Creating ${VM_DIR}/" mkdir -p "${VM_DIR}" fi # --- Create sparse disk image --- if [[ ! -f "${VM_DIR}/Disk.img" ]]; then echo "[2/4] Creating sparse disk image (${DISK_SIZE_GB} GB)" # Use dd with seek to create a sparse file (same approach as vrevm) dd if=/dev/zero of="${VM_DIR}/Disk.img" bs=1 count=0 seek="${DISK_SIZE_BYTES}" 2>/dev/null echo " -> ${VM_DIR}/Disk.img ($(du -h "${VM_DIR}/Disk.img" | cut -f1) on disk)" else echo "[2/4] Disk.img exists — skipping" fi # --- Create SEP storage --- if [[ ! -f "${VM_DIR}/SEPStorage" ]]; then echo "[3/4] Creating SEP storage (512 KB)" dd if=/dev/zero of="${VM_DIR}/SEPStorage" bs=1 count="${SEP_STORAGE_SIZE}" 2>/dev/null else echo "[3/4] SEPStorage exists — skipping" fi # --- Copy ROMs --- echo "[4/4] Copying ROMs" ROM_DST="${VM_DIR}/AVPBooter.vresearch1.bin" SEPROM_DST="${VM_DIR}/AVPSEPBooter.vresearch1.bin" if [[ -f "${ROM_DST}" ]] && cmp -s "${ROM_SRC}" "${ROM_DST}"; then echo " AVPBooter.vresearch1.bin — up to date" else cp "${ROM_SRC}" "${ROM_DST}" echo " AVPBooter.vresearch1.bin — copied ($(wc -c <"${ROM_DST}" | tr -d ' ') bytes)" fi if [[ -f "${SEPROM_DST}" ]] && cmp -s "${SEPROM_SRC}" "${SEPROM_DST}"; then echo " AVPSEPBooter.vresearch1.bin — up to date" else cp "${SEPROM_SRC}" "${SEPROM_DST}" echo " AVPSEPBooter.vresearch1.bin — copied ($(wc -c <"${SEPROM_DST}" | tr -d ' ') bytes)" fi # --- Create .gitkeep --- touch "${VM_DIR}/.gitkeep" # --- Generate VM manifest --- echo "[5/4] Generating VM manifest (config.plist)" "${SCRIPT_DIR}/vm_manifest.py" \ --vm-dir "${VM_DIR}" \ --cpu "${CPU_COUNT}" \ --memory "${MEMORY_MB}" \ --disk-size "${DISK_SIZE_GB}" || { echo "ERROR: Failed to generate VM manifest" exit 1 } echo "" echo "=== VM created at ${VM_DIR}/ ===" echo "" echo "Contents:" ls -lh "${VM_DIR}/" echo "" echo "Manifest (config.plist) saved with VM configuration." echo "Future boots will read configuration from this manifest." echo "" echo "Next steps:" echo " 1. Prepare firmware: make fw_prepare" echo " 2. Patch firmware: make fw_patch" echo " 3. Boot DFU: make boot_dfu" echo " 4. Boot normal: make boot"