1#!/bin/bash
2# Shared QEMU argument builder for hardware profiles
3# Source this file then call: build_qemu_args PROFILE SECURE_BOOT SSH_PORT TEST_DIR
4# Result is stored in the QEMU_ARGS array.
5
6[[ "${BASH_SOURCE[0]}" == "${0}" ]] && { echo "Source this file, do not execute it directly." >&2; exit 1; }
7
8OVMF_CODE_SECBOOT="/usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd"
9OVMF_VARS_TEMPLATE="/usr/share/edk2/x64/OVMF_VARS.4m.fd"
10
11build_qemu_args() {
12 local profile="$1"
13 local secure_boot="$2"
14 local ssh_port="$3"
15 local test_dir="$4"
16
17 local machine_opts="q35,vmport=off"
18 [[ "$secure_boot" == "on" ]] && machine_opts="q35,vmport=off,smm=on"
19
20 local sys_uuid
21 sys_uuid="$(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid)"
22
23 QEMU_ARGS=()
24
25 # ── Machine & CPU ────────────────────────────────────────────────────────────
26 QEMU_ARGS+=(-enable-kvm)
27 QEMU_ARGS+=(-machine "$machine_opts")
28 QEMU_ARGS+=(-cpu host)
29 QEMU_ARGS+=(-smp 4,cores=2,threads=2,sockets=1)
30 QEMU_ARGS+=(-m 4096)
31 QEMU_ARGS+=(-uuid "$sys_uuid")
32
33 # ── Firmware ─────────────────────────────────────────────────────────────────
34 if [[ "$secure_boot" == "on" ]]; then
35 local vars_copy
36 vars_copy="$(mktemp /tmp/OVMF_VARS_XXXXXXXX.fd)"
37 cp "$OVMF_VARS_TEMPLATE" "$vars_copy" || { rm -f "$vars_copy"; return 1; }
38 QEMU_ARGS+=(-global driver=cfi.pflash01,property=secure,value=on)
39 QEMU_ARGS+=(-drive "if=pflash,readonly=on,format=raw,file=${OVMF_CODE_SECBOOT}")
40 QEMU_ARGS+=(-drive "if=pflash,format=raw,file=${vars_copy}")
41 # clean up temp VARS on exit
42 trap "rm -f '$vars_copy'" EXIT
43 else
44 QEMU_ARGS+=(-bios /usr/share/edk2/x64/OVMF.4m.fd)
45 fi
46
47 # ── SMBIOS ───────────────────────────────────────────────────────────────────
48 # Type 0: BIOS
49 QEMU_ARGS+=(-smbios "type=0,vendor=American Megatrends Inc.,version=F14,date=12/01/2021,uefi=on")
50
51 case "$profile" in
52 desktop)
53 # Type 1: System
54 QEMU_ARGS+=(-smbios "type=1,manufacturer=Gigabyte Technology Co. Ltd.,product=B550 AORUS ELITE V2,version=1.0,serial=SN-DESKTOP-001,uuid=${sys_uuid},sku=Default string,family=Desktop")
55 # Type 2: Board
56 QEMU_ARGS+=(-smbios "type=2,manufacturer=Gigabyte Technology Co. Ltd.,product=B550 AORUS ELITE V2,version=x.x,serial=SN-BOARD-DESKTOP,asset=Base Board Asset Tag,location=Default string")
57 # Type 3: Chassis — desktop (type 3)
58 QEMU_ARGS+=(-smbios "type=3,manufacturer=Default string,version=Default string,serial=Default string,asset=Default string,sku=Default string")
59 ;;
60 laptop)
61 # Type 1: System — ThinkPad X1 Carbon Gen 10
62 QEMU_ARGS+=(-smbios "type=1,manufacturer=LENOVO,product=21CB,version=ThinkPad X1 Carbon Gen 10,serial=SN-LAPTOP-001,uuid=${sys_uuid},sku=LENOVO_MT_21CB,family=ThinkPad X1 Carbon Gen 10")
63 # Type 2: Board
64 QEMU_ARGS+=(-smbios "type=2,manufacturer=LENOVO,product=21CB,version=SDK0J40697 WIN,serial=SN-BOARD-LAPTOP,asset=Not Available,location=Not Available")
65 # Type 3: Chassis — notebook (type 10)
66 QEMU_ARGS+=(-smbios "type=3,manufacturer=LENOVO,version=None,serial=SN-CHASSIS-LAPTOP,asset=Not Available,sku=Not Available")
67 ;;
68 *)
69 echo "Unknown profile: $profile (expected desktop or laptop)" >&2
70 return 1
71 ;;
72 esac
73
74 # ── Storage — NVMe ───────────────────────────────────────────────────────────
75 local nvme_serial
76 case "$profile" in
77 desktop) nvme_serial="TESTDESKTOP0001" ;;
78 laptop) nvme_serial="TESTLAPTOP00001" ;;
79 esac
80 QEMU_ARGS+=(-drive "if=none,id=nvme0,format=qcow2,file=${test_dir}/arch-test.qcow2")
81 QEMU_ARGS+=(-device "nvme,drive=nvme0,serial=${nvme_serial}")
82
83 # ── Network ──────────────────────────────────────────────────────────────────
84 local nic_mac
85 case "$profile" in
86 desktop) nic_mac="52:54:00:12:34:01" ;;
87 laptop) nic_mac="52:54:00:12:34:02" ;;
88 esac
89 QEMU_ARGS+=(-netdev "user,id=net0,hostfwd=tcp::${ssh_port}-:22")
90 QEMU_ARGS+=(-device "e1000e,netdev=net0,mac=${nic_mac}")
91
92 # ── USB Controller + Input ───────────────────────────────────────────────────
93 QEMU_ARGS+=(-device qemu-xhci)
94 QEMU_ARGS+=(-device usb-kbd)
95 QEMU_ARGS+=(-device usb-tablet)
96
97 # ── Audio ─────────────────────────────────────────────────────────────────────
98 QEMU_ARGS+=(-audiodev none,id=audio0)
99 QEMU_ARGS+=(-device ich9-intel-hda)
100 QEMU_ARGS+=(-device hda-duplex,audiodev=audio0)
101
102 # ── GPU / Display ─────────────────────────────────────────────────────────────
103 # Use std VGA: works regardless of guest GPU drivers (virtio-vga needs
104 # virtio-gpu module in the guest initramfs which may not be present).
105 QEMU_ARGS+=(-device "VGA,vgamem_mb=64")
106 QEMU_ARGS+=(-display "gtk,zoom-to-fit=on")
107}