{ pkgs ? import { }, }: pkgs.writeShellApplication { name = "test-image"; runtimeInputs = [ pkgs.qemu pkgs.OVMF ]; text = '' set -euo pipefail if [ $# -lt 1 ]; then echo "Usage: $0 [x86_64|aarch64]" >&2 exit 1 fi img="$1" arch="''\${2:-$(uname -m)}" accel=( -accel kvm ) [ -e /dev/kvm ] || accel=( -accel "tcg,thread=multi" ) case "$arch" in x86_64|amd64) qemu_bin="qemu-system-x86_64" machine=( -machine q35 ) cpu=( -cpu max ) smp=( -smp 4 ) ram=( -m 4G ) pflash_code=( -drive "if=pflash,format=raw,readonly=on,file=${pkgs.OVMF.firmware}" ) pflash_vars=( -drive "if=pflash,format=raw,readonly=on,file=${pkgs.OVMF.variables}" ) ;; aarch64|arm64) qemu_bin="qemu-system-aarch64" machine=( -machine virt ) cpu=( -cpu host ) smp=( -smp 4 ) ram=( -m 4G ) # Copy VARS to a writable temp file; QEMU opens it read/write varsTmp=$(mktemp /tmp/AAVMF_VARS.fd.XXXXXX) cp ${pkgs.OVMF.fd}/FV/AAVMF_VARS.fd "$varsTmp" pflash_code=( -drive "if=pflash,format=raw,readonly=on,file=${pkgs.OVMF.fd}/FV/AAVMF_CODE.fd" ) pflash_vars=( -drive "if=pflash,format=raw,file=$varsTmp" ) ;; *) echo "Unsupported arch: $arch" >&2 exit 1 ;; esac tmpFile=$(mktemp /tmp/test-image.XXXXXX) trap 'rm -f "$tmpFile"' EXIT cp "$img" "$tmpFile" "$qemu_bin" \ "''\${accel[@]}" \ "''\${machine[@]}" \ "''\${cpu[@]}" \ "''\${ram[@]}" \ "''\${smp[@]}" \ -netdev user,id=net0,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=net0 \ "''\${pflash_code[@]}" \ "''\${pflash_vars[@]}" \ -drive "if=virtio,format=raw,file=$tmpFile" ''; }