From c139c566d055385a3b3c902ef248fa90bbe9ee34 Mon Sep 17 00:00:00 2001 From: Guofang Date: Sun, 18 Oct 2026 17:28:31 +0800 Subject: [PATCH] Use virtio-gpu with viogpudo on Arm64 Windows 11 Replace ramfb with virtio-gpu-pci at 2048x1280 and install the viogpudo driver from the VirtIO ISO. ramfb has a fixed mode, and keeping both adapters left Windows with a second, fixed-mode monitor. Windows Setup and the base image have no viogpudo driver, so on the launch that creates the system disk the launcher also adds a ramfb ahead of the config files. The display window shows the first GPU. Co-Authored-By: Claude Sonnet 5.5 --- qemu/windows11-darwin-arm64.ini | 12 ++++++++---- qemu/windows11-linux-arm64.ini | 12 ++++++++---- run-windows11.py | 7 ++++++- seediso/windows11/Configure-Windows.ps1 | 3 ++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/qemu/windows11-darwin-arm64.ini b/qemu/windows11-darwin-arm64.ini index d728f71..1470608 100644 --- a/qemu/windows11-darwin-arm64.ini +++ b/qemu/windows11-darwin-arm64.ini @@ -24,11 +24,15 @@ driver = "virtio-net-pci" netdev = "net0" -# Unlike q35, "virt" has no default GPU or keyboard. ramfb is used rather than -# virtio-gpu because the firmware's virtio-gpu output freezes at the Windows -# boot manager; Windows drives either one through its basic display driver. +# Unlike q35, "virt" has no default GPU or keyboard. virtio-gpu is the only +# display, driven by viogpudo (installed by Configure-Windows.ps1). ramfb is not +# added because Windows would then see a second adapter with a fixed-mode +# monitor. xres/yres set the preferred mode in the EDID (QEMU defaults to +# 1280x800); viogpudo accepted 1920x1200 and 2048x1280 but not 2560x1600. [device "gpu0"] - driver = "ramfb" + driver = "virtio-gpu-pci" + xres = "2048" + yres = "1280" [device "kbd0"] driver = "usb-kbd" diff --git a/qemu/windows11-linux-arm64.ini b/qemu/windows11-linux-arm64.ini index 0001bef..8de02f9 100644 --- a/qemu/windows11-linux-arm64.ini +++ b/qemu/windows11-linux-arm64.ini @@ -24,11 +24,15 @@ driver = "virtio-net-pci" netdev = "net0" -# Unlike q35, "virt" has no default GPU or keyboard. ramfb is used rather than -# virtio-gpu because the firmware's virtio-gpu output freezes at the Windows -# boot manager; Windows drives either one through its basic display driver. +# Unlike q35, "virt" has no default GPU or keyboard. virtio-gpu is the only +# display, driven by viogpudo (installed by Configure-Windows.ps1). ramfb is not +# added because Windows would then see a second adapter with a fixed-mode +# monitor. xres/yres set the preferred mode in the EDID (QEMU defaults to +# 1280x800); viogpudo accepted 1920x1200 and 2048x1280 but not 2560x1600. [device "gpu0"] - driver = "ramfb" + driver = "virtio-gpu-pci" + xres = "2048" + yres = "1280" [device "kbd0"] driver = "usb-kbd" diff --git a/run-windows11.py b/run-windows11.py index f63332c..6fe6529 100755 --- a/run-windows11.py +++ b/run-windows11.py @@ -372,7 +372,12 @@ for label, host_port, guest_port in (("RDP", rdp_port, 3389), ("SSH", ssh_port, else: forwards.append(f"hostfwd=tcp::{host_port}-:{guest_port}") -qemu_args = [ +# Neither Windows Setup nor the base image has the viogpudo driver yet, and +# without it the virtio-gpu in the config file shows "display output is not +# active". ramfb shows the screen until Configure-Windows.ps1 installs it. It +# must be created before the virtio-gpu: the display window shows the first GPU. +qemu_args = ["-device", "ramfb"] if installing and host_arch == "arm64" else [] +qemu_args += [ "-readconfig", str(qemu_config), "-readconfig", str(qemu_platform_config), # "max" is the host CPU under KVM/HVF and the fullest model under TCG. diff --git a/seediso/windows11/Configure-Windows.ps1 b/seediso/windows11/Configure-Windows.ps1 index bc37055..c9e459b 100644 --- a/seediso/windows11/Configure-Windows.ps1 +++ b/seediso/windows11/Configure-Windows.ps1 @@ -45,7 +45,8 @@ function Install-VirtIOArm64Drivers { @{ Folder = 'vioserial'; Inf = 'vioser.inf' }, @{ Folder = 'Balloon'; Inf = 'balloon.inf' }, @{ Folder = 'viorng'; Inf = 'viorng.inf' }, - @{ Folder = 'vioinput'; Inf = 'vioinput.inf' } + @{ Folder = 'vioinput'; Inf = 'vioinput.inf' }, + @{ Folder = 'viogpudo'; Inf = 'viogpudo.inf' } ) $installed = 0