Test an aarch64-linux VM wayland compositor from an x86_64-linux host

I’m trying to test a wayland setup that’s supposed to run on aarch64-linux system. More specifically I’m trying to run pinnacle from the VM’s ‘tty’ and it won’t start:

$ pinnacle
Error: The graphics api has found no node matching DrmNode { dev: 57984, ty: Render }
Failed to init gbm device
Error: Invalid argument (os error 22) /run/opengl-driver/lib/gbm, suffix _gbm)

Everything else besides that seem to work - I can ssh to it and login via tty etc. Here’s my VM specific configuration:

                # This is for making the host be able to emulate the guest system
                virtualisation.vmVariant.virtualisation.host.pkgs = pkgs;
                # Make it easier to ssh into the guest machine
                virtualisation.vmVariant.virtualisation.forwardPorts = [
                  {
                    from = "host";
                    host.port = 2222;
                    guest.port = 22;
                  }
                ];

I also found the following useful but I’m pretty sure this is not a problem:

                # Force a sane resolution - should fit most modern screens
                virtualisation.vmVariant.boot.kernelParams = [ "video=1920x1080" ];

And finally the Wayland configuration is:

  programs.pinnacle = {
    enable = true;
    xdg-portals.enable = false;
  };
  hardware.graphics.enable = true;

I tried all kind of suggestions from an LLM, like running qemu with -device virtio-gpu-gl-pci -display gtk,gl=on. And many other options I found on the internet which often made qemu-system-aarch64 not launch. Here’s the current exec line in the VM’s derivation in case that helps:

exec /nix/store/7yf84vnnsnvdi7r8g2grfpafnq17mp8y-qemu-10.2.2/bin/qemu-system-aarch64 -machine virt,gic-version=max,accel=kvm:tcg -cpu max \
    -name jukebox \
    -m 1024 \
    -smp 1 \
    -device virtio-rng-pci \
    -net nic,netdev=user.0,model=virtio -netdev user,id=user.0,hostfwd=tcp::2222-:22,"$QEMU_NET_OPTS" \
    -virtfs local,path=/nix/store,security_model=none,mount_tag=nix-store \
    -virtfs local,path="${SHARED_DIR:-$TMPDIR/xchg}",security_model=none,mount_tag=shared \
    -virtfs local,path="$TMPDIR"/xchg,security_model=none,mount_tag=xchg \
    -drive cache=writeback,file="$NIX_DISK_IMAGE",id=drive1,if=none,index=1,werror=report -device virtio-blk-pci,bootindex=1,drive=drive1,serial=root \
    -device virtio-keyboard \
    -device virtio-gpu-pci \
    -device usb-ehci,id=usb0 \
    -device usb-kbd \
    -device usb-tablet \
    -kernel ${NIXPKGS_QEMU_KERNEL_jukebox:-/nix/store/56vgk6zsp3vnjc1mxi1sd5qldw0wx7v1-nixos-system-jukebox-sd-card-26.05.20260426.4a79523/kernel} \
    -initrd /nix/store/0c1xn49xz1r6bjj0hr1gxsgri8mr9l40-initrd-linux-6.18.24/initrd \
    -append "$(cat /nix/store/56vgk6zsp3vnjc1mxi1sd5qldw0wx7v1-nixos-system-jukebox-sd-card-26.05.20260426.4a79523/kernel-params) init=/nix/store/56vgk6zsp3vnjc1mxi1sd5qldw0wx7v1-nixos-system-jukebox-sd-card-26.05.20260426.4a79523/init regInfo=/nix/store/9vl036kr2vqlxrq2hx5yv6dp9xqq8gnp-closure-info/registration console=ttyAMA0,115200n8 console=tty0 $QEMU_KERNEL_PARAMS" \
    $QEMU_OPTS \
    "$@"
1 Like

I finally figured it out:

  1. First, at least for pinnacle, seatd has to be enabled:
services.seatd.enable = true;
  1. The following qemu launcher config is needed:
                virtualisation.vmVariant.virtualisation.qemu.options = [
                  "-display gtk,gl=on"
                ];
  1. Along with the following override:
          }).config.system.build.vm.overrideAttrs
            (oldAttrs: {
              # From some reason adding another -device makes pinnacle not
              # launch, so we substitute the gpu device with an opengl enabled
              # device manually. TODO: Fix this in Nixpkgs more elegantly.
              buildCommand = oldAttrs.buildCommand + ''
                # Remove a symlink and substitue the contents of it with out
                # virtio-gpu-gl-pci fix
                original=$(readlink $out/bin/run-*)
                basename=$(basename $out/bin/run-*)
                rm $out/bin/run-*
                substitute "$original" "$out/bin/$basename" \
                  --replace-fail virtio-gpu-pci virtio-gpu-gl-pci
                chmod +x $out/bin/run-*
              '';

The full config example at this point in time is available here:

https://gitlab.com/doronbehar/nixos-configs/-/lob/78e711e99b6f5bd9b7fd340d46be690e191db6a4/flake.nix#L241-289

I hopefully will post a link to the GitHub PR that will fix this once I got it ready.