commit 42df5f9ef26eb60af7e1db352f615087ecdfe9c5
parent da28e1c13c991b2db936ccff3de467be0492b6ab
Author: finwo <finwo@pm.me>
Date: Fri, 18 Sep 2026 15:20:07 +0200
Installer wiring
Diffstat:
| M | mk/run-qemu.sh | | | 69 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/mk/run-qemu.sh b/mk/run-qemu.sh
@@ -13,6 +13,31 @@ QEMU_SSH_PORT="${QEMU_SSH_PORT:-2222}"
QEMU_MEM="${QEMU_MEM:-512}"
KERNEL="${ROOT}/rootfs/boot/vmlinuz"
+# UEFI support. OVMF's QemuKernelLoaderFsDxe makes `-kernel` work under UEFI
+# firmware, so a direct-kernel live VM still gets a real /sys/firmware/efi --
+# which the installer needs for firmware detection and for efibootmgr.
+UEFI="${UEFI:-0}"
+OVMF_CODE="${OVMF_CODE:-/usr/share/qemu/edk2-x86_64-code.fd}"
+OVMF_VARS_SRC="${OVMF_VARS_SRC:-/usr/share/qemu/edk2-i386-vars.fd}"
+OVMF_VARS="${BUILD}/ovmf-vars.fd"
+# Optional second disk, presented as /dev/vdb (install target).
+TARGET_DISK="${TARGET_DISK:-}"
+TARGET_SIZE_MB="${TARGET_SIZE_MB:-2048}"
+# Extra files to copy into the staged rootfs: "src:dstpath" pairs.
+EXTRA_FILES="${EXTRA_FILES:-}"
+
+uefi_args() {
+ [ "${UEFI}" = "1" ] || return 0
+ [ -f "${OVMF_CODE}" ] || { echo "run-qemu.sh: OVMF code not found: ${OVMF_CODE}" >&2; exit 1; }
+ # vars must be writable and per-run, otherwise boot entries persist between tests
+ [ -f "${OVMF_VARS}" ] || cp "${OVMF_VARS_SRC}" "${OVMF_VARS}"
+ printf '%s' "-drive if=pflash,format=raw,readonly=on,file=${OVMF_CODE} -drive if=pflash,format=raw,file=${OVMF_VARS}"
+}
+
+reset_uefi_vars() {
+ rm -f "${OVMF_VARS}"
+}
+
# --- collect authorized_keys (automated, no hardcoding) ---
collect_keys() {
tmp=$(mktemp)
@@ -56,6 +81,17 @@ stage_rootfs() {
cat "$keys_file" > "${STAGE}/root/.ssh/authorized_keys"
chmod 700 "${STAGE}/root/.ssh"
chmod 600 "${STAGE}/root/.ssh/authorized_keys"
+
+ # Extra payloads, "src:dst" pairs separated by whitespace. Used by the
+ # installer test to drop unos-*.bin into the live VM.
+ for pair in ${EXTRA_FILES}; do
+ src="${pair%%:*}"
+ dst="${pair#*:}"
+ [ -e "${src}" ] || { echo "run-qemu.sh: EXTRA_FILES source missing: ${src}" >&2; exit 1; }
+ mkdir -p "${STAGE}$(dirname "${dst}")"
+ cp -a "${src}" "${STAGE}${dst}"
+ echo "==> staged ${src} -> ${dst}"
+ done
chown -R 0:0 "${STAGE}/root/.ssh" 2>/dev/null || true
echo "==> injected $(wc -l < "$keys_file") key(s) into /root/.ssh/authorized_keys"
}
@@ -81,22 +117,48 @@ build_image() {
run_qemu() {
[ -f "${KERNEL}" ] || { echo "run-qemu.sh: kernel not found: ${KERNEL} (run mk/rootfs.sh first)" >&2; exit 1; }
[ -f "${IMG}" ] || { echo "run-qemu.sh: image not found: ${IMG}" >&2; exit 1; }
+ tgt=""
+ if [ -n "${TARGET_DISK}" ]; then
+ [ -f "${TARGET_DISK}" ] || truncate -s "${TARGET_SIZE_MB}M" "${TARGET_DISK}"
+ tgt="-drive file=${TARGET_DISK},format=raw,if=virtio"
+ echo " target: ${TARGET_DISK} (/dev/vdb, ${TARGET_SIZE_MB}M)"
+ fi
echo "==> launching QEMU (ssh -p ${QEMU_SSH_PORT} root@localhost)"
echo " kernel: ${KERNEL}"
echo " drive: ${IMG}"
echo " mem: ${QEMU_MEM}M"
+ echo " uefi: ${UEFI}"
echo " press Ctrl-a c then 'quit' to exit QEMU"
echo ""
# shellcheck disable=SC2086
exec qemu-system-x86_64 -enable-kvm -m "${QEMU_MEM}" \
+ $(uefi_args) \
-kernel "${KERNEL}" \
-drive file="${IMG}",format=raw,if=virtio \
+ ${tgt} \
-append "console=ttyS0 root=/dev/vda rw" \
-nographic \
-netdev user,id=net0,hostfwd=tcp::${QEMU_SSH_PORT}-:22 \
-device e1000,netdev=net0
}
+# Boot a disk that was written by the installer: no -kernel, no -append. The
+# firmware must find the ESP, run GRUB, and GRUB must find the kernel. This is
+# the only mode that actually proves the install worked.
+boot_installed() {
+ disk="$1"
+ [ -f "${disk}" ] || { echo "run-qemu.sh: no such image: ${disk}" >&2; exit 1; }
+ echo "==> booting installed disk ${disk} (no -kernel; firmware -> GRUB -> UNOS)"
+ echo " uefi: ${UEFI}"
+ # shellcheck disable=SC2086
+ exec qemu-system-x86_64 -enable-kvm -m "${QEMU_MEM}" \
+ $(uefi_args) \
+ -drive file="${disk}",format=raw,if=virtio \
+ -nographic \
+ -netdev user,id=net0,hostfwd=tcp::${QEMU_SSH_PORT}-:22 \
+ -device e1000,netdev=net0
+}
+
# --- main ---
mode="${1:-run}"
case "$mode" in
@@ -114,8 +176,13 @@ case "$mode" in
rm -f "$kf"
run_qemu
;;
+ boot-installed)
+ reset_uefi_vars
+ boot_installed "${2:-${BUILD}/unos-target.img}"
+ ;;
*)
- echo "usage: $0 [build|run]" >&2
+ echo "usage: $0 [build|run|boot-installed [img]]" >&2
+ echo " env: UEFI=1 TARGET_DISK=<path> TARGET_SIZE_MB=<n> QEMU_SSH_PORT=<n>" >&2
exit 1
;;
esac