Architecture
This guide covers Capsa's internal architecture for contributors.
Crate Structure
capsa/
├── crates/
│ ├── capsa/ # Main library, public API
│ ├── core/ # Shared types, traits, errors
│ ├── cli/ # Command-line interface
│ ├── net/ # Userspace NAT networking (smoltcp)
│ ├── linux/
│ │ └── kvm/ # Linux KVM backend
│ └── apple/
│ ├── vz/ # macOS Virtualization.framework bindings
│ ├── vzd/ # macOS VM daemon
│ └── vzd-ipc/ # IPC protocol for vzd
└── nix/
└── test-vms/ # Test VM definitionsCrate Responsibilities
| Crate | Purpose |
|---|---|
capsa | Public API surface. Re-exports types from capsa-core. Contains VmBuilder, VmHandle, VmConsole. |
capsa-core | Shared types used across backends: configs, errors, traits |
capsa-net | Userspace networking stack using smoltcp. Handles NAT, DHCP, DNS proxy, network policies. |
capsa-linux-kvm | KVM backend implementation. Memory setup, device emulation, interrupt routing. |
capsa-apple-vz | Swift/ObjC bindings to Virtualization.framework |
capsa-apple-vzd | Daemon process that manages VMs on macOS |
capsa-apple-vzd-ipc | tarpc-based IPC protocol between capsa and vzd |
Linux KVM Backend
Memory Layout
The Linux KVM backend sets up guest memory with this layout:
0x0000_7000 Boot parameters
0x0000_8000 Stack
0x0000_9000 Page tables (PML4)
0x0002_0000 Kernel command line
0x0100_0000 Kernel load address (16 MB)
0x0400_0000 Initrd load address (64 MB)Virtio Devices
All devices use MMIO transport with direct interrupt injection:
| Device | Base Address | IRQ |
|---|---|---|
| Console | 0x100000 | 5 |
| Network | 0x1400000 | 4 |
| vsock | 0x1500000 | 6 |
| Filesystem | 0x1600000+ | 10+ |
Interrupts
- IOAPIC with 24 pins
- MP table at 0x9fc00 for interrupt routing
- Each virtio device gets a dedicated IRQ line
macOS Backend
Subprocess Architecture
Virtualization.framework requires certain operations to run on the main thread. Since Rust async applications typically use worker threads, Capsa uses a subprocess architecture:
┌─────────────────────────────────────┐
│ Your Application (Tokio) │
│ capsa library │
└─────────────────┬───────────────────┘
│ IPC (tarpc)
┌─────────────────▼───────────────────┐
│ capsa-apple-vzd daemon │
│ (manages main thread for VZ) │
└─────────────────┬───────────────────┘
│
┌─────────────────▼───────────────────┐
│ Virtualization.framework │
└─────────────────────────────────────┘VZD Daemon
The capsa-apple-vzd binary is automatically spawned when needed. It's searched for in:
CAPSA_VZD_PATHenvironment variable- Same directory as your executable
- System PATH
For development, the dev shell ensures vzd is built and available.
Code Signing
Virtualization.framework requires the com.apple.security.virtualization entitlement. During development, the dev shell provides codesign-run which signs binaries on-the-fly:
# The dev shell handles this automatically via cargo aliases
cargo test-macosFor distribution, you must sign your binary with proper entitlements:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.virtualization</key>
<true/>
</dict>
</plist>