commit 199a458af2dc4ab6a269c981430a925956f01c1f
Author: MikoĊaj Lenczewski <mblenczewski@gmail.com>
Date: Fri, 14 Nov 2025 23:19:00 +0000
Initial commit
Diffstat:
5 files changed, 145 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+*.fd
+*.img
diff --git a/vmcommon.sh b/vmcommon.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+ARCH="${ARCH:-aarch64}"
+
+case $ARCH in
+ x86_64)
+ MACHINE="q35"
+ QEMU_EFI_CODE="/usr/share/qemu/edk2-x86_64-code.fd"
+ QEMU_EFI_VARS="/usr/share/qemu/edk2-i386-vars.fd"
+ ;;
+
+ aarch64)
+ MACHINE="virt"
+ QEMU_EFI_CODE="/usr/share/qemu/edk2-aarch64-code.fd"
+ ;;
+
+ *)
+ echo "Unknown architecture, must be one of: aarch64 x86_64"
+ exit 1
+ ;;
+esac
+
+DISK="$(dirname $0)/vmroot-$ARCH.xfs.img"
+
+EFI_CODE="$(dirname $0)/efi-$ARCH-code.fd"
+EFI_VARS="$(dirname $0)/efi-$ARCH-vars.fd"
+
+NUMA="${NUMA:-2}"
+NUMA_CORES="4"
+NUMA_MEMGB="4"
+
+NUMA_TOTAL_CORES="$(( $NUMA * $NUMA_CORES ))"
+NUMA_TOTAL_MEMGB="$(( $NUMA * $NUMA_MEMGB ))"
+
+NUMA_TASKSET="taskset -c 0-$(( $NUMA_TOTAL_CORES - 1 ))"
+
+NUMA_FLAGS=""
+
+for i in $(seq 0 $(( $NUMA - 1 ))); do
+ min_cpu="$(( $i * $NUMA_CORES ))"
+ max_cpu="$(( (($i + 1) * $NUMA_CORES) - 1 ))"
+
+ NUMA_FLAGS="$NUMA_FLAGS -object memory-backend-ram,id=mem$i,size=${NUMA_MEMGB}G,host-nodes=0,policy=bind"
+ NUMA_FLAGS="$NUMA_FLAGS -numa node,memdev=mem$i,cpus=$min_cpu-$max_cpu,nodeid=$i"
+done
+
+NUMA_FLAGS="-smp cpus=$NUMA_TOTAL_CORES,sockets=$NUMA,maxcpus=$NUMA_TOTAL_CORES"
+NUMA_FLAGS="-m ${NUMA_TOTAL_MEMGB}G"
diff --git a/vmdisk.sh b/vmdisk.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+. "$(dirname $0)/vmcommon.sh"
+
+MIB="$(( 1024 * 1024 ))"
+SECTOR="512"
+
+DISK_SIZE_GIB="64"
+UEFI_PART_MIB="512"
+
+UEFI_PART_START="2048"
+UEFI_PART_SECTORS="$(( ($UEFI_PART_MIB * $MIB) / $SECTOR ))"
+ROOT_PART_START="$(( $UEFI_PART_START + $UEFI_PART_SECTORS ))"
+
+set -ex
+
+# create disk
+[ -e $DISK ] || \
+ dd if=/dev/zero of=$DISK bs=1G count=$DISK_SIZE_GIB status=progress
+
+cat <<EOF | sfdisk $DISK
+unit: sectors
+label: gpt
+
+type=U, start=$UEFI_PART_START, size=$UEFI_PART_SECTORS, bootable
+type=L, start=$ROOT_PART_START
+EOF
+
+# format partitions
+LOOPDEV="$(losetup -f -P $DISK --show)"
+
+mkfs.vfat -F32 -n VM-ESP ${LOOPDEV}p1
+mkfs.xfs -f -L VM-ROOT ${LOOPDEV}p2
+
+losetup -d $LOOPDEV
diff --git a/vminstall.sh b/vminstall.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+NUMA="1"
+
+. "$(dirname $0)/vmcommon.sh"
+
+ISO="$1"
+
+if [ -z $ISO ]; then
+ echo "Usage: $0 <live-image.iso>"
+ exit 1
+fi
+
+set -ex
+
+# create efi files
+case $ARCH in
+ x86_64)
+ dd if=$QEMU_EFI_VARS of=$EFI_VARS conv=notrunc
+ dd if=$QEMU_EFI_CODE of=$EFI_CODE conv=notrunc
+ ;;
+
+ aarch64)
+ dd if=/dev/zero of=$EFI_VARS bs=1M count=64
+ dd if=/dev/zero of=$EFI_CODE bs=1M count=64
+ dd if=$QEMU_EFI of=$EFI_CODE conv=notrunc
+ ;;
+esac
+
+qemu-system-$ARCH \
+ -M $MACHINE -cpu host -enable-kvm $NUMA_FLAGS \
+ -drive if=pflash,format=raw,file=$EFI_CODE,readonly=yes \
+ -drive if=pflash,format=raw,file=$EFI_VARS \
+ -drive if=none,format=raw,file=$(realpath $DISK),id=hd0 \
+ -drive if=none,format=raw,file=$(realpath $ISO),id=cd0,readonly=yes \
+ -device virtio-blk,drive=hd0 \
+ -device virtio-scsi-pci,id=scsi0 \
+ -device scsi-cd,bus=scsi0.0,drive=cd0 \
+ -device virtio-net-pci,netdev=net0 \
+ -netdev user,id=net0,hostfwd=tcp::8022-:22 \
+ -device virtio-rng-pci,rng=rng0 \
+ -object rng-random,filename=/dev/urandom,id=rng0 \
+ -nographic -serial mon:stdio
diff --git a/vmstart.sh b/vmstart.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+. "$(dirname $0)/vmcommon.sh"
+
+set -ex
+
+$NUMA_TASKSET qemu-system-$ARCH \
+ -M $MACHINE -cpu host -enable-kvm $NUMA_FLAGS \
+ -drive if=pflash,format=raw,file=$EFI_CODE,readonly=yes \
+ -drive if=pflash,format=raw,file=$EFI_VARS \
+ -drive if=none,format=raw,file=$(realpath $DISK),id=hd0 \
+ -device virtio-blk,id=hd0 \
+ -device virtio-net-pci,netdev=net0 \
+ -netdev user,id=net0,hostfwd=tcp::8022-:22 \
+ -device virtio-rng-pci,rng=rng0 \
+ -object rng-random,filename=/dev/urandom,id=rng0 \
+ -nographic -serial mon:stdio -display curses