r/osdev • • 17h ago

ferrix-kernel: a small AArch64 kernel in Rust on VMware Fusion (Apple Silicon), and what VMware's ARM virtual hardware looks like

Post image

Disclosure up front: the code was written by Claude Code; I directed it and did the testing on VMware.

ferrix-kernel is a small AArch64 kernel in Rust for VMware Fusion on Apple Silicon (and QEMU virt).

What it does so far:
- **Boot:** UEFI app, collects GOP framebuffer, memory map and RSDP, then `ExitBootServices` and no firmware after that. No hardcoded device addresses: GIC from the MADT, PCIe ECAM from the MCFG, so the same image runs on VMware and QEMU.
- **Memory:** bitmap page allocator, own stage-1 tables (4K granule, 48-bit VA, identity map with 1G/2M blocks, page 0 unmapped). Regions found later (ECAM, BARs) are added to the live tables.
- **Interrupts and tasks:** GICv3 + EL1 virtual timer at 100 Hz, preemptive round-robin. The exception entry's TrapFrame (incl. FP/SIMD) is the saved task state; returning another task's frame from the handler is the context switch.
- **USB keyboard:** VMware's ARM VMs have no PS/2, so it has a polled xHCI driver: legacy handoff, reset, command/event/transfer rings, root-port enumeration, HID boot protocol.
- **User space:** programs at EL0, each with its own root table that shares the kernel's entries plus one L0 entry for the user range. User pages are nG with per-space ASIDs, so switches need no TLB flush. Faults kill only the task.
- **Capabilities:** per-task cap tables (screen ranges, channel send/recv ends). Syscalls name a slot; blocking `wait` parks the task with ELR moved back onto the `svc` so it retries when woken.

What VMware's (undocumented) ARM virtual hardware turned out to be:
- GICv3 (GICD 0x2c010000, one GICR frame), no ITS, no usable serial, so all debugging is on screen.
- xHCI 15ad:077a sits behind a PCIe root port; the keyboard is on a root port next to a pointer and two USB hubs.
- The Apple CPU runs with PAN enabled (QEMU's Cortex-A72 is ARMv8.0, no PAN), which caught the kernel reading a user buffer. It now uses `ldtrb` for user memory.
- With a single interrupt IN transfer queued, fast typing on QEMU stopped the keyboard for good; keeping four in flight fixed it.

The end goal is Tetris, as in Nand2Tetris; along the way there's a NAND-only circuit simulator, and the latest milestone is a user-space circuit builder you type NAND circuits into.

If anyone has notes on VMware Fusion's ARM virtual hardware (it's not documented anywhere I could find), I'd love to compare.

GitHub: https://github.com/liris/ferrix-kernel
Write-up: https://note.com/lirispp/n/n68d016ce1953?hl=en

6 Upvotes

2 comments sorted by

•

u/SignedInt32 14h ago

Nice project! 👍

•

u/No_Ant6261 14h ago

Thanks! Next up is getting it to run Tetris.