TechTip: Fixing "Display Output Is Not Active" on Arch Linux ARM (UTM/QEMU, Apple Silicon)

Also published at: Substack

This took a while to fix, so recording my notes, in case I need to remember how to fix it in the future.

Symptoms

After running pacman -Syu on an Arch Linux ARM (aarch64) VM running under UTM on Apple Silicon, the VM appears to be broken:

Display output is not active

In reality, the VM is booting successfully -- the display driver (virtio_gpu) simply cannot load.

Root Causes

There are up to three issues at play:

1. Kernel Module Mismatch (Primary Cause)

When pacman -Syu upgrades the linux-aarch64 kernel package, it:

If the VM is not rebooted after the upgrade, the running kernel has zero loadable modules because its module directory no longer exists. This includes virtio_gpu, the display driver used by UTM’s virtual GPU. Without it, the screen goes blank.

You can confirm this by booting the VM with a serial console (see Diagnosis via Serial Console below) and running:

uname -r                  # Shows running kernel version
ls /lib/modules/          # Shows installed module directories
lsmod | grep virtio       # Will be empty if modules can't load

2. Stale vmlinuz-linux File

The linux-aarch64 package installs the kernel image as /boot/Image and /boot/Image.gz. However, GRUB’s grub-mkconfig looks for /boot/vmlinuz-linux first.

If a vmlinuz-linux file exists from a previous setup (e.g., a different kernel package or manual installation), GRUB will boot it instead of the current Image. After a kernel upgrade, this stale file still contains the old kernel, perpetuating the module mismatch even after a reboot.

You can confirm this by comparing the files:

ls -la /boot/Image /boot/vmlinuz-linux
# Different sizes and/or dates indicate a mismatch

3. GRUB efi_uga.mod Error (Cosmetic)

On every boot, GRUB displays:

error: fs/fshelp.c:find_file:260:file `/grub/arm64-efi/efi_uga.mod' not found.
Press any key to continue...

This happens because GRUB’s load_video function (generated by /etc/grub.d/00_header) tries to load the efi_uga module on all EFI systems. UGA (Universal Graphics Adapter) is an x86-only EFI protocol and the module does not exist on aarch64. The error is non-fatal but pauses the boot process.

Solution

Step 1: Boot via Serial Console

Since the display is non-functional, use QEMU directly from the macOS terminal with a serial console to access the VM.

First, ensure UTM is not running. Then create and run a boot script:

#!/bin/bash
# rescue-serial.sh - Boot Arch Linux ARM VM with interactive serial console
# Quit QEMU: press Ctrl-A then X

QEMU=qemu-system-aarch64
EFI_CODE=/opt/homebrew/share/qemu/edk2-aarch64-code.fd
EFI_VARS="/path/to/rescue-efi-vars.fd"
VM_DISK="/path/to/your-vm-disk.qcow2"

# Create a fresh EFI vars file (required: must be 64 MB for QEMU's virt machine)
cp /opt/homebrew/share/qemu/edk2-arm-vars.fd "$EFI_VARS"

exec "$QEMU" \
  -M virt \
  -cpu host \
  -accel hvf \
  -smp 4 \
  -m 4096 \
  -drive if=pflash,format=raw,file="$EFI_CODE",readonly=on \
  -drive if=pflash,format=raw,file="$EFI_VARS" \
  -drive file="$VM_DISK",format=qcow2,if=virtio \
  -device virtio-net-pci,netdev=net0 \
  -netdev user,id=net0 \
  -nographic

Important notes:

After running the script, you should see a login prompt in your terminal. Log in normally.

Step 2: Fix the Kernel Image

Replace the stale vmlinuz-linux with the current kernel:

sudo rm /boot/vmlinuz-linux
sudo cp /boot/Image /boot/vmlinuz-linux

Step 3: Regenerate Initramfs and GRUB Config

sudo mkinitcpio -P
sudo grub-mkconfig -o /boot/grub/grub.cfg

Warnings about missing firmware for hardware not present in the VM (amdgpu, nouveau, etc.) are normal and can be ignored.

Step 4: Fix the efi_uga.mod Error

Comment out the efi_uga references in the GRUB config generator:

sudo sed -i 's/insmod efi_uga/#insmod efi_uga/' /etc/grub.d/00_header
sudo grub-mkconfig -o /boot/grub/grub.cfg

Step 5: Prevent Future Occurrences

Create two pacman hooks to automatically handle these issues on future upgrades.

Hook 1: Copy kernel image for GRUB

sudo mkdir -p /etc/pacman.d/hooks
sudo tee /etc/pacman.d/hooks/linux-aarch64-vmlinuz.hook << 'EOF'
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = linux-aarch64

[Action]
Description = Copying Image to vmlinuz-linux for GRUB...
When = PostTransaction
Exec = /bin/cp /boot/Image /boot/vmlinuz-linux
EOF

Hook 2: Patch GRUB for aarch64

sudo tee /etc/pacman.d/hooks/grub-fix-efi-uga.hook << 'EOF'
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = grub

[Action]
Description = Removing efi_uga references from grub (not available on aarch64)...
When = PostTransaction
Exec = /bin/sed -i 's/insmod efi_uga/#insmod efi_uga/' /etc/grub.d/00_header
EOF

Step 6: Reboot

Shut down the VM (sudo poweroff), close the QEMU serial session, and boot the VM normally in UTM. The display should now work.

Diagnosis via Serial Console

If you encounter display issues with a UTM VM in the future, booting via QEMU with -nographic provides a serial console that bypasses the display entirely. This is invaluable for diagnosing

blank screen

VMs that may actually be booting fine.

Key diagnostic commands once logged in:

uname -r                          # Running kernel version
ls /lib/modules/                  # Available module directories
lsmod | grep virtio               # Loaded virtio modules
dmesg | grep -i drm               # DRM/GPU initialization
dmesg | grep -i virtio            # Virtio device detection
ls -la /dev/dri/                  # GPU device nodes
journalctl -b -p err --no-pager   # Boot errors

Summary

IssueCauseFixBlank display after kernel upgradeRunning kernel’s modules deleted by pacmanReboot into new kernelStill blank after rebootGRUB boots stale vmlinuz-linux instead of ImageReplace with cp /boot/Image /boot/vmlinuz-linuxefi_uga.mod error on bootGRUB loads x86-only module on aarch64Patch /etc/grub.d/00_headerRecurrence on future upgradesNo automatic sync between Image and vmlinuz-linuxPacman hooks