Skip to content

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 definitions

Crate Responsibilities

CratePurpose
capsaPublic API surface. Re-exports types from capsa-core. Contains VmBuilder, VmHandle, VmConsole.
capsa-coreShared types used across backends: configs, errors, traits
capsa-netUserspace networking stack using smoltcp. Handles NAT, DHCP, DNS proxy, network policies.
capsa-linux-kvmKVM backend implementation. Memory setup, device emulation, interrupt routing.
capsa-apple-vzSwift/ObjC bindings to Virtualization.framework
capsa-apple-vzdDaemon process that manages VMs on macOS
capsa-apple-vzd-ipctarpc-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:

DeviceBase AddressIRQ
Console0x1000005
Network0x14000004
vsock0x15000006
Filesystem0x1600000+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:

  1. CAPSA_VZD_PATH environment variable
  2. Same directory as your executable
  3. 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:

bash
# The dev shell handles this automatically via cargo aliases
cargo test-macos

For distribution, you must sign your binary with proper entitlements:

xml
<?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>

Released under the MIT License.