This guide covers the internal architecture of the vmctl CLI tool.
apps/vmctl/src/
└── main.rs Single-file application (~1400 lines)
vmctl is intentionally a single-file application — all CLI parsing, VM setup, and execution logic is in main.rs.
CLI args parsing
│
▼
VM configuration
(RAM, BIOS, disks, network, etc.)
│
▼
libcorevm setup
(create VM, configure devices, load BIOS, attach media)
│
▼
Execution loop
(run VM, handle exits, render framebuffer, inject input)
│
▼
Shutdown / timeout
Arguments are parsed manually from std::env::args(). The run subcommand is the primary (and currently only) command.
vmctl uses libcorevm's Rust API directly (not FFI):
- Creates a
Vmwith the specified RAM - Loads BIOS firmware (CoreVM or SeaBIOS)
- Configures devices based on CLI flags:
- E1000 NIC (if networking enabled)
- AHCI or IDE controller
- SVGA or VGA display
- AC'97 audio
- Attaches disk images and ISOs
- Sets boot order and cache mode
The VM runs in the main thread:
- Calls
corevm_run()in a loop - Handles VM exits (I/O, HLT, shutdown)
- If
-gflag: renders framebuffer - If
-kflag: injects keyboard input at scheduled times - If
-tflag: checks timeout and stops if exceeded - Continues until shutdown, error, or timeout
| Platform | Feature | Backend |
|---|---|---|
| Linux | libcorevm/linux |
KVM |
| Crate | Purpose |
|---|---|
libcorevm |
VM engine (with platform feature) |
vmctl has minimal dependencies — only libcorevm itself.
- Add argument parsing for the new subcommand in
main.rs - Implement the subcommand logic
- Call from the main dispatch
- Add the option to the argument parser
- Pass the value to the VM configuration
- Document the option in the help text and user guide