What Virtual Devices Are Configured for the vphone-cli VM: Complete Hardware Emulation Breakdown
The vphone-cli VM configures 13+ virtual devices including graphics, audio, storage, network, serial, multi-touch, accelerators, entropy, keyboard, socket, battery, debug stub, and Secure Enclave coprocessor to emulate a complete iPhone hardware platform.
The vphone-cli project by Lakr233 creates a macOS virtual machine using Apple's Virtualization.framework to run iOS environments. Understanding what virtual devices are configured for the vphone-cli VM requires examining the VPhoneVirtualMachine.init method in sources/vphone-cli/VPhoneVirtualMachine.swift, where the VZVirtualMachineConfiguration is assembled. This article breaks down every emulated device category with direct source references.
Core Virtual Devices Overview
The VM construction follows a pattern: each device type is instantiated with platform-specific configurations, then assigned to the configuration object. Some use public Apple APIs, while hardware-accurate features rely on private API calls through Dynamic wrappers.
Graphics Device: VZMacGraphicsDeviceConfiguration
The display subsystem uses VZMacGraphicsDeviceConfiguration with a single VZMacGraphicsDisplayConfiguration that specifies width, height, and DPI to match iPhone screen characteristics.
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L61-L69
let gfx = VZMacGraphicsDeviceConfiguration()
let display = VZMacGraphicsDisplayConfiguration(
widthInPixels: options.screenWidth,
heightInPixels: options.screenHeight,
pixelsPerInch: options.screenPPI
)
gfx.displays = [display]
config.graphicsDevices = [gfx]
This creates a Retina-compatible virtual display that iOS renders into.
Audio Device: VZVirtioSoundDeviceConfiguration
Audio emulation uses VirtIO with separate input and output stream configurations:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L71-L78
let afg = VZVirtioSoundDeviceConfiguration()
affg.streams = [
VZVirtioSoundDeviceInputStreamConfiguration(), // Microphone input
VZVirtioSoundDeviceOutputStreamConfiguration() // Speaker output
]
config.audioDevices = [afg]
The VZVirtioSoundDeviceConfiguration provides standard audio device semantics that iOS audio drivers recognize.
Storage Device: VZVirtioBlockDeviceConfiguration
Persistent storage attaches a disk image through a virtIO block interface:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L80-L86
let attachment = VZDiskImageStorageDeviceAttachment(
url: options.diskURL,
readOnly: false
)
let block = VZVirtioBlockDeviceConfiguration(attachment: attachment)
config.storageDevices = [block]
The VZVirtioBlockDeviceConfiguration presents the VM's root filesystem to iOS as a standard block device.
Network Device: VZVirtioNetworkDeviceConfiguration
Networking is optional and mode-configurable through VPhoneNetworking.makeNetworkDevice:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L87-L92
if let net = VPhoneNetworking.makeNetworkDevice(options: options) {
config.networkDevices = [net]
} else {
config.networkDevices = []
}
The implementation in sources/VPhoneCore/VPhoneNetworking.swift#L92-L115 supports three modes:
- NAT — isolated VM with outbound connectivity
- Bridged — full network integration with host interface
- None — no network device attached
Serial Port: VZSerialPortConfiguration
A PL011 UART provides console access for debugging and boot logging:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L94-L122
let serialPort = VZSerialPortConfiguration()
let inputPipe = Pipe()
let outputPipe = Pipe()
serialPort.attachment = VZSerialPortAttachment(
fileHandleForReading: inputPipe.fileHandleForReading,
fileHandleForWriting: outputPipe.fileHandleForWriting
)
config.serialPorts = [serialPort]
Host processes read VM output from outputPipe and send input through inputPipe.
Private API Devices: Hardware-Accurate Emulation
Several iPhone-specific devices require private Virtualization.framework APIs, accessed through Dynamic runtime binding.
GPU Accelerators
Three accelerator types provide hardware media and ML capabilities:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L24-L30
Dynamic(config)._setAcceleratorDevices([
VZMacVideoToolboxDeviceConfiguration(), // Video codec acceleration
VZMacNeuralEngineDeviceConfiguration(), // Core ML / ANE access
VZMacScalerAcceleratorDeviceConfiguration() // Image scaling operations
])
These expose host Apple Silicon media engines to the guest iOS environment.
Multi-Touch Input: VZUSBTouchScreenConfiguration
Touch screen emulation uses a USB HID device:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L32-L36
let touch = VZUSBTouchScreenConfiguration()
Dynamic(config)._setMultiTouchDevices([touch])
The VZUSBTouchScreenConfiguration translates host touch events into iOS-compatible multi-touch reports.
Power Source: VZMacSyntheticBatterySource
Battery state emulation enables iOS battery monitoring APIs:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L50-L57
let battery = VZMacSyntheticBatterySource()
let batteryDevice = VZMacBatteryPowerSourceDeviceConfiguration(
battery: battery
)
Dynamic(config)._setPowerSourceDevices([batteryDevice])
The VZMacSyntheticBatterySource reports synthetic charge states that iOS Settings and apps can query.
Additional Virtual Devices
Entropy Device: VZVirtioEntropyDeviceConfiguration
Cryptographic randomness for the guest kernel:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L38-L40
let entropy = VZVirtioEntropyDeviceConfiguration()
config.entropyDevices = [entropy]
This feeds hardware-derived random data into iOS's entropy pool.
Keyboard: VZUSBKeyboardConfiguration
Standard USB HID keyboard for text input:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L42-L44
config.keyboards = [VZUSBKeyboardConfiguration()]
Socket Device: VZVirtioSocketDeviceConfiguration
Host-guest communication channel (vsock), conditionally enabled:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L44-L48
if !options.noVphoned {
let socket = VZVirtioSocketDeviceConfiguration()
config.socketDevices = [socket]
}
When enabled, the host-side client in sources/vphone-cli/VPhoneControl.swift connects to this for VM management.
Debug Infrastructure
Two debugging facilities support development workflows:
GDB Debug Stub — remote debugging protocol implementation:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L61-L78
let debugStub = VZGDBDebugStubConfiguration(
port: options.debugPort ?? 0 // 0 = system-assigned
)
Dynamic(config)._setDebugStub(debugStub)
Secure Enclave Coprocessor — SEP emulation with optional ROM and dedicated debug stub:
// From sources/vphone-cli/VPhoneVirtualMachine.swift#L80-L88
let sep = VZSEPCoprocessorConfiguration()
if let romURL = options.romURL {
sep.rom = VZSEPCoprocessorROMConfiguration(url: romURL)
}
sep.debugStub = VZGDBDebugStubConfiguration(port: sepDebugPort)
Dynamic(config)._setCoprocessors([sep])
The VZSEPCoprocessorConfiguration is essential for iOS features requiring Secure Enclave services.
Inspecting Configured Devices at Runtime
After VM initialization, you can verify device configuration through the public VZVirtualMachineConfiguration API:
// Inspecting what virtual devices are configured for the vphone-cli VM
if let graphics = vm.configuration?.graphicsDevices?.first
as? VZMacGraphicsDeviceConfiguration {
let display = graphics.displays.first
print("Display: \(display?.widthInPixels ?? 0)×\(display?.heightInPixels ?? 0) @ \(display?.pixelsPerInch ?? 0) PPI")
}
print("Audio devices: \(vm.configuration?.audioDevices?.count ?? 0)")
print("Storage devices: \(vm.configuration?.storageDevices?.count ?? 0)")
print("Network devices: \(vm.configuration?.networkDevices?.count ?? 0)")
print("Serial ports: \(vm.configuration?.serialPorts?.count ?? 0)")
print("Socket devices: \(vm.configuration?.socketDevices?.count ?? 0)")
print("Keyboards: \(vm.configuration?.keyboards?.count ?? 0)")
Source File Reference
| File | Purpose |
|---|---|
sources/vphone-cli/VPhoneVirtualMachine.swift |
Central VM construction and all device configuration |
sources/VPhoneCore/VPhoneNetworking.swift |
Network device factory with NAT/bridged/none modes |
sources/vphone-cli/VPhoneControl.swift |
Host-side vsock client implementation |
research/VPhoneVirtualMachineRefactored.swift |
Extended reference implementation with detailed comments |
The primary configuration logic spans approximately 100 lines in VPhoneVirtualMachine.swift, assembling what virtual devices are configured for the vphone-cli VM through sequential property assignments on VZVirtualMachineConfiguration.
Summary
- Graphics, audio, storage, and network use public Virtualization.framework APIs with VirtIO and Mac-specific device configurations
- Serial ports, entropy, keyboard, and socket provide standard PC-compatible interfaces that iOS drivers recognize
- Accelerators, multi-touch, battery, debug stub, and SEP require private API access via
Dynamicruntime calls to achieve iPhone hardware fidelity - Conditional devices (network, socket) depend on runtime options; debug infrastructure is development-only
- All device creation is centralized in
VPhoneVirtualMachine.initwith clear separation between public API usage and private hardware emulation
Frequently Asked Questions
How does vphone-cli achieve iPhone-specific hardware emulation?
The project combines public Virtualization.framework APIs for standard devices with private API calls through Swift runtime dynamic dispatch. Standard devices (storage, audio, network) use documented VZVirtio*Configuration classes. iPhone-specific features like the Secure Enclave, Neural Engine, and synthetic battery require _set methods on VZVirtualMachineConfiguration that Apple does not expose publicly—these are accessed via Dynamic(config)._setAcceleratorDevices() and similar patterns.
Can I disable specific virtual devices when creating a vphone-cli VM?
Some devices are conditionally configured based on VPhoneVirtualMachine.Options. Set noVphoned: true to disable the VZVirtioSocketDeviceConfiguration. Network can be disabled by omitting network configuration parameters. However, core devices (graphics, audio, storage, keyboard, entropy) are mandatory and always attached—modifying these requires editing sources/vphone-cli/VPhoneVirtualMachine.swift directly.
What resolution and DPI does the vphone-cli VM display use?
The display configuration uses parameters from Options.screenWidth, Options.screenHeight, and Options.screenPPI. Typical iPhone values are 1125×2436 at 458 PPI for iPhone X-class devices, or 1170×2532 at 460 PPI for iPhone 12/13. These map to VZMacGraphicsDisplayConfiguration properties that iOS renders into at native Retina density.
Where is the VM disk image attached in the storage configuration?
The VZVirtioBlockDeviceConfiguration receives a VZDiskImageStorageDeviceAttachment initialized with options.diskURL, typically pointing to an APFS or HFS+ formatted raw disk image containing the iOS root filesystem. This attachment is marked read-write by default (readOnly: false), allowing persistent state across VM restarts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →