go-virtio
Pure-Go, transport-agnostic virtio guest drivers — no cgo, no kernel.
go-virtio is a family of Go modules that implement virtio device-class
drivers in pure Go and route every transport-level operation through one
narrow interface, so the same driver code works under UEFI's
EFI_PCI_IO_PROTOCOL, bare-metal MMIO, virtio-mmio, TamaGo, and anything
else that can satisfy the contract. It replaces the fragmented in-tree
virtio code that each Go project reinvents with one reusable,
well-tested, transport-pluggable driver set. Extracted from the
cloud-boot TamaGo + UEFI loader, but
designed to run anywhere virtio runs.
How the pieces fit
net rng vsock blk console balloon fs input sound gpu ← spec-level drivers
└────┴─────┴─────┴──────┴────────┴──────┴─────┴──────┴─────┘
│
┌─────────────▼──────────────┐
│ go-virtio/common │ transport-agnostic infra
│ PCI cap walker · ModernConfig · split-virtqueue ·
│ descriptor chaining · device IDs · Transport interface
└─────────────┬──────────────┘
│ Transport (PCIConfigReader,
│ BARMemoryAccessor, PageAllocator)
┌────────────────────────▼──────────────────────────────────────┐
│ EFI_PCI_IO_PROTOCOL · bare-metal MMIO · virtio-mmio · TamaGo … │ host backplane
└────────────────────────────────────────────────────────────────┘
Every driver consumes common.Transport and
nothing else. Swap the backplane, keep the driver.
virtio is little-endian
The virtio rings and config registers are defined little-endian on
the wire. The shared common virtqueue/register code carries the
byte-order handling for the driver set (its ring code was recently
fixed for big-endian hosts).
The drivers
| Module | Device (DID) | What it does |
|---|---|---|
common |
— | Shared infrastructure: PCI cap walker, modern-config registers, split-virtqueue + descriptor chaining, device-class IDs, the Transport interface. |
net |
virtio-net (0x1041) | Frame-level TransmitFrame / ReceiveFrame over a TX/RX queue pair. |
rng |
virtio-rng (0x1044) | Single-queue entropy Read — the minimal device class. |
vsock |
virtio-vsock (0x1053) | Three queues; packet-level SendPacket / ReceivePacket with virtio_vsock_hdr. |
blk |
virtio-blk (0x1042) | ReadBlocks / WriteBlocks / Flush; header + data + status descriptor chains. |
console |
virtio-console (0x1043) | Raw byte-stream Write / Read over an rx/tx pair. |
balloon |
virtio-balloon (0x1045) | Inflate / Deflate via le32 page-frame-number arrays. |
fs |
virtio-fs (0x105A) | FUSE-over-virtio read-write mount: Lookup/Open/Read + Write/Create/Mkdir/SetAttr/Rename/… |
input |
virtio-input (0x1052) | Keyboard + relative-pointer event read path (input_event wire format). |
sound |
virtio-sound (0x1059) | Minimal PCM playback + capture over the control / tx / rx queues. |
gpu |
virtio-gpu (0x1050) | 2D framebuffer + virgl 3D + a pure-Go software 3D rasterizer (gpu/soft3d). |
venus |
virtio-gpu | Vulkan-over-virtio (Venus): a vk.xml→Go serializer/generator plus a ring transport; clear-image end-to-end with guest-side pixel readback. |
validate |
— | Real-hardware validation harness (TamaGo + QEMU) and a pure-Go virglrenderer/Venus vtest client. |
The 3D story
go-virtio/gpu makes the honest split explicit — "pure-Go 3D" is three
different things:
- Software (CPU).
gpu/soft3dis a dependency-free, z-buffered triangle rasterizer that renders into the virtio-gpu framebuffer. Works on any host, no GPU. - virgl (host GPU).
gpuhand-encodes the virgl command stream (shaders shipped as TGSI text) so a hostvirglrendererdoes the drawing — real hardware acceleration, still CGO=0. - Vulkan / Venus.
venusserialises the Vulkan API over a virtio ring; a clear-image runs end-to-end on a real renderer, with guest-side pixel readback on a Linux render-node host.
See Components for the per-module pages.