← Back · sub-plan of the NextBSD graphics plan, which covers the shipped amd64 stack (bochs, vboxvideo, Intel/AMD/Radeon, NVIDIA)
/dev/dri/card0 in an ARM virtual machineThe amd64 graphics stack is done — BochsGraphics and VBoxGraphics ship, Intel and AMD bind on real hardware. arm64 has nothing, and neither does anyone else: two independent research sweeps of the FreeBSD mailing lists, Bugzilla, Phabricator, forums and GitHub found zero reports of /dev/dri in any arm64 FreeBSD VM, ever. This page lays out every route to changing that, with honest costs, so the choice can be made from evidence rather than from my summary of it.
Settled 2026-08-16 The DRM stack builds on aarch64. nextbsd-kernel-modules#33 compiles drm.ko, ttm.ko, dmabuf.ko, radeonkms.ko and our drm_extra_helpers.ko for arm64 and verifies every resulting kext resolves against the arm64 kernel. That was an open question; it no longer is. What is missing is not the DRM core — it is a driver that binds something an ARM VM actually presents.
Decided 2026-08-16 This page is now the decision record — it shows how the route was chosen, not what is open. The outcome:
/dev/dri/card0 and a render node, dynamic resolution, and hardware-accelerated OpenGL through Mesa's virgl. Not a framebuffer stand-in. Execution plan: NextBSD virtio-gpu DRM.ArmVirtQemu ships no QemuVideoDxe. Black from power-on is not shippable.AMDGraphics (upstream cannot make it loadable there) and no RadeonGraphics (matches only discrete PCIe cards, which an ARM VM does not present). Implemented in PR #33.Two findings since have made Option E materially smaller than costed below: the LinuxKPI virtio shim needs no FreeBSD base change, and the entire Mesa/virgl userland already ships in ports. Both are in the execution plan.
Facts, not plans. Each was verified directly rather than inferred.
| Fact | Evidence |
|---|---|
drm-kmod's core builds on aarch64: drm, ttm, dmabuf, amdgpu, radeonkms, plus our helper module | PR #33 CI, 2026-08-16. drm-kmod (arm64) built: drm amdgpu radeonkms |
i915 is correctly absent on arm64 | drm-kmod Makefile adds i915 to DEFAULT_KMODS for amd64/i386 only |
Upstream's amdgpu.ko cannot load on aarch64 | kconfig.mk gates DRM_AMD_DC_FP behind .if ${MACHINE_CPUARCH} == "amd64", dropping the Display Core FP sources while references stay compiled. Five undefined symbols (dal_hw_factory_dcn401_init, dal_hw_translate_dcn401_init, three dscl*_spl_calc_lb_num_partitions) → kldload ENOEXEC. Caught by tools/check-kext-symbols.py |
| There is no aarch64-capable drm port at all | graphics/drm-510-kmod, the last with aarch64 in ONLY_FOR_ARCHS, was deleted 2026-05-05 |
| FreeBSD base has no LinuxKPI virtio shim | 249 headers in sys/compat/linuxkpi/common/include/linux/ on main; zero occurrences of the string “virtio” anywhere under sys/compat/linuxkpi. Same on releng/15.1 |
drm-kmod 6.12-lts ships no tiny/, sysfb/, virtio/ or vmwgfx/, and no drm_gem_shmem_helper.c | Full file-tree listing of 6.12-lts and master |
FreeBSD's native virtio_gpu(4) is a vt(4) console framebuffer only — no DRM, no /dev/dri, no 3D | VT_DRIVER_DECLARE(vt_vtgpu, ...); added 2023-08-17 by andrew@, sponsored by Arm Ltd (D40094). Restated on freebsd-virtualization 2026-07: “a simple 2D/scanout driver with no virgl support” |
Nobody has ever reported /dev/dri in an arm64 FreeBSD VM | Two independent exhaustive sweeps: freebsd-arm, -x11, -virtualization, -drivers, -current, -hackers, -ports, Bugzilla, forums, Phabricator, GitHub |
Everything below this section is evidence. These are the calls that evidence does not make for you — each one changes what gets built next. Marked blocking where work cannot start until it is answered.
This single answer picks the whole near-term route.
drm_dev_alloc().These are not mutually exclusive in the long run — B is a stepping stone that E does not invalidate — but they compete for the next block of effort.
Everything vendored so far is GPL-2.0-or-later, and graphics/README.md states that as an invariant. drm_gem_shmem_helper.c, simpledrm.c and the whole sysfb/ family are GPL-2.0-only.
Worth deciding deliberately rather than by accident: the stated long-term direction for this code is migration toward FreeBSD base, and that is exactly the conflict evadot raised on PR #119. A decision here should also either amend or reaffirm the README invariant.
Option D costs nothing and is orthogonal to everything else: hint.virtio_pci.1.disabled="1" keeps efifb (which has vd_fb_mmap) instead of letting vtgpu displace it, giving working X11-on-llvmpipe in UTM today. The only argument against is that it may mask the problem a real driver should solve.
Decide before writing, because it is hard to change later and one choice silently breaks Wayland:
ttm/ and drm_gem_ttm_helper.c; adds no new code.drm_gem_vram_helper — already built and shipping, but a VRAM pool over the EFI aperture is exactly one screen's worth: fine for Xorg modesetting, fatal for Wayland compositors that want two or more buffers.RadeonGraphics? low stakesIt builds and resolves cleanly on aarch64, but only matters for a discrete AMD card in a physical PCIe slot — never in a VM. Ship it (costs build time, serves ARM server hardware) or drop it (keeps the arm64 package to what VMs use). Currently shipped in PR #33.
amdgpu/aarch64 defect? outward-facingdrm-kmod's DRM_AMD_DC_FP gating produces an amdgpu.ko that builds clean and cannot load on aarch64, and nothing upstream checks for it. Options: report it upstream, fix it locally and carry a patch, or leave it and keep the guard in PR #33. Reporting is a project-representation decision, so it is being left alone pending a call.
kldload hang reported against drm-kmod 6.12 (dsl@ and evadot, Jan 2026). If it is a drm.ko core path rather than amdgpu-specific, every option here is blocked until it is understood. Testable now by loading our arm64 IOGraphics.kext in a VM.lspci -nn in an ARM guest decides whether Option F is addressable at all.Both are hours of work and could invalidate weeks of it.
drm-kmod is FreeBSD's out-of-tree port of Linux's DRM subsystem. Driver source is copied from Linux and patched as little as possible; branches track Linux LTS releases (5.4-lts … 6.12-lts); FreeBSD Makefiles replace Kbuild. The Linux kernel API those files call is not in drm-kmod — it comes from LinuxKPI, which lives in FreeBSD base at sys/compat/linuxkpi. The project's stated preference is to add to LinuxKPI rather than patch drivers, so a fix is not applied twice.
So any missing piece can live in one of three places, and choosing wrongly means either carrying a patch forever or waiting on someone else:
| Layer | Repository | What belongs there | Our leverage |
|---|---|---|---|
| LinuxKPI | FreeBSD base | linux/virtio.h, devres wrappers, gen_pool | None directly — needs a base commit |
| drm-kmod | freebsd/drm-kmod | vendored Linux DRM + FreeBSD glue | PRs only; the virtio PR has sat 5 years |
| ours | nextbsd-kernel-modules | whatever the two above omit | Total — this is the only layer we control |
Everything shipped so far is layer 3. graphics/drm_extra_helpers now carries four files that drm-kmod either does not ship or ships and never compiles:
drm_simple_kms_helper.c not shipped by drm-kmod
drm_gem_vram_helper.c not shipped by drm-kmod
drm_gem_atomic_helper.c header is a 15-line stub; zero shadow-plane code
drm_format_helper.c IN drm-kmod's tree, EXPORT_SYMBOLs intact,
named by no Makefile anywhere — dead code upstream
That last one is worth remembering when estimating any option below: a file being present in drm-kmod does not mean it is built, and a driver building does not mean it loads. Both traps have already cost this project a CI cycle each.
This is a genuine decision input, and it is not the one stated earlier in this project. There is no maintainer edict against any specific file. What exists is a licence boundary that our own repo already promises to respect — graphics/README.md states “Sources are GPL-2.0-or-later, as is the rest of the vendored Linux DRM code.”
| File | SPDX | Status here |
|---|---|---|
drm_gem_vram_helper.c | GPL-2.0-or-later | vendored, shipping |
drm_simple_kms_helper.c | GPL-2.0-or-later | vendored, shipping |
tiny/bochs.c | GPL-2.0-or-later | vendored, shipping |
drm_gem_shmem_helper.c | GPL-2.0-only | would be new |
tiny/simpledrm.c | GPL-2.0-only | would be new |
sysfb/efidrm.c, drm_sysfb*.c | GPL-2.0-only | would be new |
Note Dropping the shmem helper does not rescue simpledrm — simpledrm.c is itself GPL-2.0-only. Any option that imports Linux's framebuffer-DRM code crosses this line twice. The only way to get that functionality while keeping the or-later invariant is to write the driver rather than import it (Option B).
Whether GPL-2.0-only is actually disqualifying for NextBSD is a project decision, not a technical one. It matters more than usual here because the stated long-term direction for this code is migration toward base.
bochs.ko on arm64Ruled out Cost: days. Rejected on direct observation.
The idea. bochs-display is instantiable on qemu-system-aarch64 -M virt and is listed in UTM's own generated aarch64 device table (QEMUConstantGenerated.swift:6537). It is PCI 1234:1111 with BAR0 framebuffer and BAR2 MMIO and no legacy VGA I/O ports, which is exactly why it survives on ARM. hw/arm/sbsa-ref.c instantiates it unconditionally. Gerd Hoffmann's widely-cited 2019 claim that PCI-memory-BAR displays fail on ARM was corrected by QEMU's ARM maintainer: the failure needs KVM-on-Arm and a host lacking FEAT_S2FWB, and Apple M1+ are Armv8.5-A, so it does not apply. We already build every helper bochs needs.
Why it is out. Tested directly in UTM: no display at all, before any driver handoff. ArmVirtPkg/ArmVirtQemu.dsc ships only QemuRamfbDxe under “Video support” — there is no QemuVideoDxe, so the firmware never drives the device. Even if bochs.ko bound after kldload, the machine is black from power-on through loader, kernel boot and single-user. That is not shippable for a desktop OS, and pairing it with -device ramfb to cover the gap means running two display devices to get one working screen.
Recorded here because the analysis is sound and the conclusion is not obvious — if a future ARM firmware ships QemuVideoDxe (as SbsaQemu.dsc already does), this becomes viable at near-zero cost.
Recommended near-term Cost: 1–3 weeks. ~400–600 lines.
The idea. Bind the framebuffer the firmware has already lit, rather than any device. FreeBSD's loader.efi records the UEFI GOP in MODINFOMD_EFI_FB, and sys/dev/vt/hw/efifb/efifb.c — all 5,442 bytes of it — reads the framebuffer address, stride, dimensions and colour masks straight out of it:
efifb = (struct efi_fb *)preload_search_info(preload_kmdp,
MODINFO_METADATA | MODINFOMD_EFI_FB);
info->fb_stride = efifb->fb_stride * (info->fb_bpp / NBBY);
info->fb_pbase = efifb->fb_addr;
A DRM driver consumes the identical structure. Take bochs.c as the template, replace PCI BAR discovery with that preload_search_info() call, and delete the mode-setting — one fixed mode, one CRTC/encoder/connector on drm_simple_kms_helper.
Why it fits. There is no black-screen gap by construction: firmware paints, efifb paints, then the DRM driver takes over the same buffer and publishes card0. That is the efifb → drmfb handover already proven on amd64, sourced from firmware metadata instead of a BAR. It works on every arm64 VM that boots UEFI — UTM, Parallels, Fusion, Apple Virtualization.framework, Hetzner — because it binds firmware output rather than a device. UTM defaults to virtio-ramfb, so the framebuffer is already there and already working.
What it costs in licence terms: nothing. No shmem, no virtio shim, no GPL-2.0-only imports. drm_simple_kms_helper, drm_gem_atomic_helper and drm_format_helper are already built and exported in IOGraphicsExtras.kext.
The scanout target is fixed iomem; a GEM allocator is needed only for client-side buffers, which are then blitted in. Three choices:
ttm/ and drm_gem_ttm_helper.c. Cleanest; adds no new code. Recommended.drm_gem_vram_helper — already built, but a VRAM pool over the EFI aperture is exactly one screen's worth. Fine for Xorg modesetting (one scanout BO + cursor); fatal for Wayland compositors that want two or more buffers.card0 but no render node, so llvmpipe/swrast. evadot's own framing of SimpleDRM: “you still have software accel (and so need swrast/llvmpipe) but can talk with KMS to the driver meaning wayland software will work.”Upside beyond us: this closes drm-kmod #269 (open since 2023-12-01, “currently there is no way to use Wayland e.g. in VMs”) and #389, both with standing demand and no implementation. No other BSD has one either — OpenBSD and NetBSD use wsfb/genfb.
simpledrm / efidrm verbatimPossible, but dominated by B Cost: 2–4 weeks + a GPL-2.0-only decision.
Linux moved simpledrm out of tiny/ in April 2025 into drivers/gpu/drm/sysfb/ and added efidrm, an EFI-specific variant closer to what we want, landing in 6.16.
| File | Lines | Note |
|---|---|---|
sysfb/efidrm.c | 434 | closest fit |
sysfb/simpledrm.c | 906 | |
sysfb/drm_sysfb_modeset.c | 608 | shared |
v6.12 tiny/simpledrm.c | 1,076 | pre-split, self-contained |
ofdrm is irrelevant (depends on ... (PPC || COMPILE_TEST), reads an Open Firmware device tree, exists for PowerPC Macs) and vesadrm is x86-only. simpledrm and efidrm are the only arch-neutral members.
Why B dominates it. Both select DRM_GEM_SHMEM_HELPER, so this inherits the shmem port and GPL-2.0-only code twice over. LinuxKPI is also missing linux/sysfb.h and linux/screen_info.h, which are precisely how efidrm.c finds the framebuffer — and on FreeBSD that whole layer collapses into the four-line preload_search_info() call above. You would be deleting the parts that differ and keeping the parts we can already write.
If the shmem helper is wanted anyway: it is 782 lines, and its dependencies are in better shape than expected — drm_gem_get_pages/put_pages are present and exported in drm-kmod's drm_gem.c, and LinuxKPI already has shmem_fs.h, dma_map_sgtable() and set_pages_array_wc(). Note the familiar trap: drm_fbdev_shmem.c sits in drm-kmod's tree and appears in no Makefile.
Interim unblock, not KMS Cost: days, or zero.
The problem it solves. sys/dev/virtio/gpu/virtio_gpu.c:121 declares .vd_fb_mmap = NULL, /* No mmap as we need to signal the host */, while vt_efifb sets .vd_fb_mmap = vt_fb_mmap. vtgpu's priority is VD_PRIORITY_GENERIC+10 against efifb's +1, so on any VM presenting a virtio-gpu it displaces efifb and removes the mmap xf86-video-scfb needs — giving scfb_mmap: Invalid argument.
D55012 (Tiago Gasiba, tiga@FreeBSD.org, created 2026-01-31, “Needs Review”, not committed) implements the vt(4) framebuffer mmap plus a ~30 fps host-flush task issuing TRANSFER_TO_HOST_2D + RESOURCE_FLUSH, with hw.virtio_gpu.* tunables. Confirmed working by a third party on bug 283646. andrew@ objected to the polling design, which is likely why it has sat six months.
Notably, Gasiba's own test platform is “FreeBSD 15 (arm64) running on MacOS 26.2 and UTM” — our exact target.
It does not produce /dev/dri. Framebuffer/scfb only: X11 on llvmpipe, no DRM device, no render node, no modesetting, no Wayland.
Zero-cost equivalent available today: keep efifb (which already has vd_fb_mmap) by stopping vtgpu attaching — hint.virtio_pci.1.disabled="1" in /boot/device.hints, or nodevice virtio_gpu. newbus honours this generically via resource_disabled().
The real prize, and the real cost Cost: months. Four separable sub-projects.
Why it is wanted. It is the only display device Apple's Virtualization.framework and Parallels offer, Parallels ships VirGL 3D, and it is the only option here that gives dynamic resolution — resize the window, the guest follows.
What it needs, none of which exists in shippable form:
linux_virtio.c). D32372 is a usable design sketch but has sat in “Needs Review” since 2021, was never committed, depends on another uncommitted review (D32371), calls a virtio_alloc_virtqueues() signature removed in 2023, and its virtio_reset/virtio_del_vqs are panic() stubs. A rewrite informed by it, not a rebase.drm_gem_shmem_helper (782 lines, GPL-2.0-only) — virtio-gpu genuinely needs it (drm_gem_shmem_create, _get_pages_sgt, _object_{mmap,pin,vmap}), unlike Option B where it is incidental.virtgpu_drv.c there calls drm_fbdev_generic_setup(), which no longer exists.drm_dev_alloc().Licence: mostly MIT, except the vram bits, which are GPLv2 (Linux 16845c5d5409).
Prerequisite vmwgfx is blocked by nextbsd-kernel#71 before any of the porting cost below is even reached. vmwgfx is heavily TTM-based with VRAM-resident scanout buffers, so it takes the identical is_iomem fault path that currently blocks indefinitely for bochs: once a buffer is pinned for scanout it moves into device memory, and the fault handler feeds a device-BAR pfn to a function that assumes managed shmem pages. Porting vmwgfx without fixing that path first yields a driver that binds, creates card0, and then hangs on first access — precisely the bochs outcome.
Genuinely supports ARM64 — but largest, and one hypervisor Cost: months. 1.12 MB across 57 files.
Contrary to an assumption made earlier in this project, vmwgfx is not x86-only. Linux's Kconfig reads depends on (X86 && HYPERVISOR_GUEST) || ARM64, added by VMware's Zack Rusin in 523375c943e5 (2021-05-05, “drm/vmwgfx: Port vmwgfx to arm64… ARM support is provided in svga version 3”), which split the hypervisor backdoor into vmwgfx_msg_x86.h and vmwgfx_msg_arm64.h.
Broadcom's own KB 315602 confirms vmwgfx is the display driver for Arm guests on Apple Silicon, with accelerated 3D on kernel 5.19+ and Mesa 22.1.1+. The device is SVGA3 (VMWGFX_PCI_ID_SVGA3 0x0406), not SVGA2 (0x0405).
Against it: vmwgfx_execbuf.c alone is 140 KB, versus 19 KB for all of bochs.c. It buys exactly one hypervisor. Prior FreeBSD art is dead — vmwgfx and vboxvideo were removed from drm-kmod in 787a917018a3 (2021-10-08, “haven't been compiled or working for more than a year”). ravynsoft's vmware branch reached “vmwgfx now compiles” (2023-12-28) but never “works”, with vmwgfx_page_dirty.c gutted to five empty // FIXME bodies and a documented memory leak in the validation path.
| Option | Cost | card0 | Render node / 3D | Dynamic res | Display from power-on | New GPL-2.0-only | Works on |
|---|---|---|---|---|---|---|---|
| A bochs on arm64 | days | probable | no | yes* | no — black until kldload | no | qemu/UTM only |
| B native efidrm | 1–3 wk | yes | no (llvmpipe) | no | yes | no | every UEFI arm64 VM |
| C port simpledrm | 2–4 wk | yes | no (llvmpipe) | no | yes | yes, twice | every UEFI arm64 VM |
| D D55012 / hint | 0–days | no | no | no | yes | no | UTM, Parallels |
| E virtio-gpu | months | yes | yes (virgl) | yes | yes | vram bits only | UTM, Parallels, AVF |
| F vmwgfx | months | yes | yes | yes | yes | no | VMware Fusion only |
* Option A's mode-setting works, but is moot given the boot-time blackout.
The decision in one sentence. If software-rendered Wayland at a fixed resolution is acceptable on arm64, Option B is weeks and carries no licence cost; if dynamic resolution or 3D is required, Option E is unavoidable and is a months-long project with three prerequisites before the driver is even reached. Option D is worth doing regardless as a same-day unblock, because it is free.
| Effort | State | Verdict |
|---|---|---|
| drm-kmod PR #119 Alex Richardson, 2021-10-08 |
Open/draft. Linux 5.5. Compiles; panics on attach — page fault at 0x30 in drm_sysfs_minor_alloc(). virtgpu_bsdmodule.c passes an uninitialised struct linux_virtio_device into virtio_gpu_probe(). Author, 2024-02: “I stopped working on this a long time ago.” |
Design reference. ~5 years and 12 kernel releases stale. Its VIRTIO_DRIVER_MODULE-on-native-virtio-bus attach pattern (~120 lines, BSD-2-Clause) is the salvageable part. |
| D32372 LinuxKPI virtio Richardson, 2021-10-08 |
“Needs Review” — never accepted, never committed. Depends on D32371, also never committed. Already API-broken. | Usable sketch; needs rewriting. |
ravynsoft/drm-kmod virtio |
Does not compile — literal syntax error in linux_virtio.c (stray paren, missing semicolon), introduced 2022-07-16 and never fixed. Would not link even so: calls vq_ring_must_notify_host()/vq_ring_notify_host(), both static in FreeBSD. drm_gem_shmem_helper.c implementation absent entirely. Unrelated git history to that fork's main. |
Dead end. Last commit 2022-07-17. ravynOS itself uses the stock graphics/drm-kmod port. |
ravynsoft vmware |
Linux 5.17 vmwgfx on a 6.1 core; “vmwgfx now compiles” 2023-12-28. Nobody ever claimed it runs. vmwgfx_page_dirty.c has five empty // FIXME: what is needed here? FreeBSD branches; documented memory leak in vmwgfx_validation.c. |
Porting knowledge is valuable (backdoor hypercall, Makefile, LinuxKPI tweaks); the 47.5k-line diff is not — 6.12's vmwgfx is a different driver. |
| bsd-sbc-drm/drm-subtree Jesper Schmitz Mouridsen (jsm@) |
Active — last push 2026-08-10. Ships drm_kmod.ko, rk_vop.ko, rk_drm.ko etc. as loadable DRM modules on arm64, rebased onto drm-kmod, on 15-/16-CURRENT. |
Read this first. The only working demonstration that DRM drivers link and load on FreeBSD/arm64 against modern drm-kmod. Build methodology directly reusable; the Rockchip SoC driver content is not. |
| D55012 Tiago Gasiba (tiga@) |
“Needs Review”. Third-party confirmed working. Tested on FreeBSD 15 arm64 under UTM on macOS. | Complementary, not competing — scfb/X11, not DRM. |
Corrected Two claims made earlier in this project were wrong and are retracted here so they do not propagate.
1. scripts/diffignore is not a licensing blacklist. It was cited as evidence that drm-kmod “refuses” drm_gem_shmem_helper.c. It is in fact the ignore-list for drm-kmod's own diff tooling (drmdiff, drmcheck) — the set of upstream paths to skip when diffing against Linux, i.e. “files drm-kmod does not carry”. Its first three entries are Kconfig, Kconfig.*, Makefile, and it also lists drm_gem_vram_helper.c, drm_gem_atomic_helper.c and drm_gem_framebuffer_helper.c — three files we have already vendored and ship. Presence there carries no policy verdict.
2. The GPL objection was overstated. What is sourceable is evadot objecting on PR #119 to GPL-2.0 files specifically because they conflict with moving code into the FreeBSD base system — which does not obviously bind an out-of-tree kld. No blanket refusal of the shmem helper exists. The real constraint is the narrower or-later vs only line, which our own README asserts.
Also corrected: vmwgfx was assumed x86-only; it supports ARM64 upstream and is the display driver for Arm guests on Apple Silicon. And bochs was described as invalid on arm64 for lack of a VGA device; the device is in fact instantiable and listed in UTM's own device table — it is firmware, not the device, that makes Option A unusable.
Both have real DRM drivers upstream; neither is in drm-kmod, and neither was in this plan's original six options. Verified against Linux v6.12.
drivers/gpu/drm/hyperv/ cheapest follow-onFive files, in Linux since 5.14. A proper KMS driver for Hyper-V synthetic video, and critically it is shmem-backed, not VRAM:
#include <drm/drm_gem_shmem_helper.h>
DRM_GEM_SHMEM_DRIVER_OPS,
drm_fbdev_shmem_setup(dev, 0);
That places it on the same side of the line as virtio-gpu: it would not hit the device-memory defect (nextbsd-kernel#71) that stops every VRAM-backed driver, and it needs the same prerequisite — drm_gem_shmem_helper, the 782-line GPL-2.0-only file drm-kmod omits.
Why it is the cheapest follow-on: it shares virtio-gpu's single largest cost, so once that helper exists Hyper-V is mostly the driver itself. And unlike virtio, the transport is not starting from zero — FreeBSD ships Hyper-V support in base (hv_vmbus and friends), where LinuxKPI has no virtio bus at all.
drivers/gpu/drm/xen/ not recommendedFourteen files: a paravirtual DRM frontend over Xen's display protocol, with its own event channels (xen_drm_front_evtchnl.c), config layer, and a bespoke GEM implementation (xen_drm_front_gem.c).
The graphics driver is the small part of this job. It sits on Xen guest infrastructure — grant tables, xenbus — which is an entire KPI surface that does not exist, and which nothing else we want would reuse. Citrix Hypervisor guests can in any case use the standard emulated devices, so this buys little that is not already covered.
| Driver | Backing | Needs | Relative cost |
|---|---|---|---|
| virtio-gpu | shmem | shmem helper + a LinuxKPI virtio bus shim (none exists) | months |
| hyperv_drm | shmem | shmem helper + vmbus glue (base already has hv_vmbus) | less than virtio-gpu |
| vmwgfx | VRAM | nothing new, but 1.12 MB across 57 files | months |
| xen-drm-front | bespoke GEM | Xen grant tables + xenbus KPI, none of which exists | most |
Recorded for later consideration, not proposed now. The question this answers: having built the VRAM/KMS helper layer for bochs and vboxvideo, which other upstream drivers become cheap?
The deflating answer Almost every small driver migrated to shmem years ago. bochs and vboxvideo were effectively the last drm_gem_vram_helper holdouts, so the VRAM work unlocked exactly the two drivers it was written for — there is no queue of easy VRAM drivers behind it.
| Driver | Backing | Blocked on | Why it might matter |
|---|---|---|---|
ast (ASPEED BMC) | shmem | shmem helper | arm64 and amd64 servers. Kconfig is depends on DRM && PCI && MMU with no arch constraint; ASPEED BMCs are what Ampere/Marvell-class arm64 server boards actually ship. The strongest hardware case on this list |
mgag200 (Matrox BMC) | shmem | shmem helper | Server BMCs, mostly x86 (Dell iDRAC / HPE iLO lineage) |
cirrus | shmem | shmem helper | Legacy qemu; largely superseded by bochs |
hyperv | shmem | shmem helper | Hyper-V guests. Transport already in FreeBSD base (hv_vmbus) — see §9 |
simpledrm / sysfb | shmem | shmem helper | Any UEFI machine, any arch. See the fallback plan, which proposes writing this natively instead |
qxl | TTM + drm_gem_ttm_helper | nothing new | The cheapest driver on the board. 168 KB, and drm-kmod already ships and compiles both helpers it needs. A qemu/SPICE device, so unlike vboxvideo CI could actually exercise it |
It is not virtio-gpu's private cost. One prerequisite gates six drivers — virtio-gpu, hyperv, ast, mgag200, cirrus and simpledrm — including the BMC driver that matters on real arm64 server hardware. That is a materially stronger argument for paying it than “virtio-gpu needs it”.
qxl needs no new helper layer at all. The caution: drm-kmod issue #62 records someone's qxl attempt panicking inside ttm_bo_vm_fault. Now that the device-memory defect is understood (nextbsd-kernel#71), that reads like the same bug — qxl has VRAM and would need the same vm_phys_fictitious_reg_range() registration. Suggestive, not proven.
Raspberry Pi (vc4), Rockchip, Allwinner and friends are a different problem, and none of the helper work applies. vc4's Kconfig alone:
depends on ARCH_BCM2835
depends on RASPBERRYPI_FIRMWARE # VideoCore firmware mailbox
depends on SND && SND_SOC # ALSA, for HDMI audio
depends on COMMON_CLK # Linux clock framework
select DRM_GEM_DMA_HELPER # CMA -- a third backing type
select DRM_DISPLAY_HDMI_STATE_HELPER
659 KB, needing a CMA GEM helper, the common clock framework, device-tree attachment, an ALSA/SoC binding and a firmware mailbox — none of which exists here. The only working precedent for DRM on FreeBSD/arm64 is bsd-sbc-drm (jsm@), whose Rockchip drivers are exactly this shape. If SBCs ever become a target, that is a separate track with its own prerequisites and should be scoped as one.
kldload hang reported against drm-kmod 6.12 (dsl@ and evadot, Jan 2026) is amdgpu-specific or touches drm.ko core paths. This one matters for Option B — if it is a core path, every option here is blocked until it is understood.15ad:0406 is a strong inference from the Kconfig and Rusin's commit, but no lspci -nn dump was found. Decides whether Option F is even addressable.VZVirtioGraphicsDeviceConfiguration exposes virtio-gpu over PCI or MMIO, and whether FreeBSD arm64 boots under AVF with graphics at all.bsd-sbc-drm/drm-subtree's modules/Makefile internals — not read. It is the one place someone else has solved “build a DRM kmod for aarch64 against drm-kmod”.Source to distrust freebsdsoftware.org, “State of Wayland on FreeBSD in 2026” (2026-04-09) claims virtio-gpu works with Wayland compositors on FreeBSD and that nouveau has limited drm-kmod support. Both are false — drm-kmod ships neither driver. Likely generated content; do not cite it.
Reflecting the stated preference that arm64 carry only what an ARM VM can actually use, rather than everything that happens to compile.
| Driver | amd64 | arm64 | Why |
|---|---|---|---|
IOGraphics / TTM / DMABuf / IOGraphicsExtras | ship | ship | Core + helpers. Prerequisite for every option; already builds and resolves |
IntelGraphics | ship | — | drm-kmod gates i915 to amd64/i386; no Intel iGPU on aarch64 |
AMDGraphics | ship | cannot | Upstream DRM_AMD_DC_FP gating makes amdgpu.ko unloadable on aarch64 |
RadeonGraphics | ship | optional | Builds and resolves; only relevant for a discrete card in a PCIe slot, not a VM |
BochsGraphics | ship | — | Option A: black screen until kldload on ARM firmware |
VBoxGraphics | ship | — | VirtualBox guests are x86 |
| NVIDIA | ship | — | No aarch64 legacy blob |
| EFIGraphics (Option B) | optional | target | Would also give amd64 VMs a firmware-framebuffer KMS fallback |
| VirtIOGraphics (Option E) | eventual | eventual | The only path to dynamic resolution and 3D |
Sub-plan of the NextBSD graphics plan. Written 2026-08-16 from a three-agent research sweep; every factual claim above was checked against a primary source (repository file, commit, review, mailing-list post or CI log) rather than inferred, and the items that could not be confirmed are listed in §8 rather than smoothed over. Where this page contradicts something said earlier in the project, §7 says so explicitly.