Skip to content

First light: the kernel paints a framebuffer - #92

Merged
ecto merged 1 commit into
claude/kernel-perf-slabfrom
claude/kernel-ramfb
Aug 18, 2026
Merged

First light: the kernel paints a framebuffer#92
ecto merged 1 commit into
claude/kernel-perf-slabfrom
claude/kernel-ramfb

Conversation

@ecto

@ecto ecto commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Stacked on #91 (targets that branch; retarget to main once it merges).

A Loon program draws rectangles on a 640×480 display, as the kernel, through
an Fb effect that falls through the handler stack to a ramfb driver — the
same shape as Console.write falling through to the UART.

make -C crates/loon-kernel gui         # cocoa window, stays up
make -C crates/loon-kernel screenshot  # headless → screenshot.png via QMP

What's here

src/fwcfg.rs QEMU fw_cfg via its DMA interface, used to find etc/ramfb
src/ramfb.rs linear XRGB framebuffer in RAM that QEMU scans out; tell it once, then drawing is writing memory
Fb effects width, height, clear, fill-rect, present — integer-only ABI (coords, sizes, 0xRRGGBB)
boot/gui.oo first light: bars getting bluer, and a loon with an eye
tools/screenshot.py headless boot, wait for gui up on serial, QMP screendump, PPM→PNG with no dependencies

Reviewer notes

  • Raster stays in Rust behind rect-sized primitives on purpose. At ~500 ns/op, per-pixel Loon is ~150 ms per frame. What lives in Loon is the what, not the how.
  • Headless boots are unaffected. Ramfb::init returns None without -device ramfb, the GUI image is skipped, and the machine powers off as before. make check and the unikernel_boot test still pass. If a program does perform Fb on a display-less machine, it gets a loud error naming the missing device, not ().
  • fw_cfg is all-DMA. The DMA interface is byte-order-defined (big-endian) and width-agnostic, so it sidesteps the question of how the data register serialises. One 64-bit BE write of the descriptor address, then poll control for zero.
  • Host::fb(op, &[i64]) is name-dispatched rather than an enum so the VM doesn't need to know what a display can do; the machine decides and says loudly when it can't.
  • Kernel is warning- and clippy-clean; cargo test --workspace green.

Not yet

Text (needs an embedded bitmap font), input (virtio-input — the next real piece), a host-side Fb handler so make check can diff the GUI the way it diffs the console, and any notion of time in an event loop.

🤖 Generated with Claude Code

A Loon program draws rectangles on a 640x480 display, as the kernel, through
an `Fb` effect that falls through the handler stack to a ramfb driver — the
same shape as `Console.write` falling through to the UART.

- src/fwcfg.rs: QEMU fw_cfg via its DMA interface, to find `etc/ramfb`.
- src/ramfb.rs: a linear XRGB framebuffer in RAM that QEMU scans out. Tell
  it where the buffer is once; drawing is writing memory. No queues, no
  interrupts.
- `Fb` effects: width, height, clear, fill-rect, present. Integer-only ABI
  (coords, sizes, 0xRRGGBB). Raster is Rust behind rect-sized primitives on
  purpose — per-pixel Loon would be ~150 ms/frame at current speed.
- boot/gui.oo runs only when the machine has a display; headless boots skip
  it and `make check` is unaffected. Without a ramfb, Fb ops raise a loud
  error naming the missing device.
- `make gui` boots with a cocoa window and stays up. `make screenshot`
  boots headless, waits for the GUI, and pulls the frame over QMP as a PNG
  (tools/screenshot.py, no dependencies) — the CI-shaped way to prove the
  display works.

Not yet: text, input, host-side Fb parity, time in the event loop.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
loon Ready Ready Preview Aug 18, 2026 3:27pm

Request Review

@ecto
ecto merged commit a17b1d2 into claude/kernel-perf-slab Aug 18, 2026
6 checks passed
ecto added a commit that referenced this pull request Aug 18, 2026
Land #92 on main (first light framebuffer)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant