Install Windows 3.11
Overview
This skill provides guidance for setting up legacy Windows virtual machines (particularly Windows 3.11) using QEMU with web-based remote access. The core challenge is not just launching the VM, but verifying it reaches a usable state and providing reliable remote access.
Critical Success Criteria
Before marking any VM setup task complete, verify:
- The VM actually boots to the expected state - Screenshots, VNC connection tests, or QMP display queries must confirm the desktop/expected state
- Web interface is fully functional - End-to-end test through the browser, not just service status checks
- Keyboard/mouse input works - Verify input actually affects VM state, not just that commands are accepted
Approach
Phase 1: Environment Assessment
Before installing anything:
- Check QEMU version requirements in task description - note any specific version compatibility statements
- Audit existing nginx configuration to understand current server blocks
- Identify required ports and check for conflicts
- Determine the disk image format and any special QEMU flags needed
Phase 2: QEMU Configuration
When configuring QEMU for legacy operating systems:
- Memory allocation: Windows 3.11 typically needs 16-64MB RAM. Check image documentation for requirements
- VNC setup: Use for display 1 (port 5901). Consider
-vnc :1,share=ignore-disconnects
for stability
- QMP socket: Enable with
-qmp unix:/path/to/qmp.sock,server,nowait
for programmatic control
- Display: Legacy OS may need specific display settings like or
Example QEMU command structure:
bash
qemu-system-i386 \
-m 32 \
-hda /path/to/disk.img \
-vnc :1 \
-qmp unix:/tmp/qmp.sock,server,nowait \
-vga std
Phase 3: Web Access Stack
The typical stack for web-based VNC access:
Browser → nginx (port 80) → websockify → VNC server (QEMU)
nginx configuration approach:
- First, examine for existing server blocks
- Check if is included in the main config
- Create configuration in the appropriate location to avoid conflicts
- Test configuration with before reloading
websockify setup:
bash
websockify --web=/usr/share/novnc 6080 localhost:5901
Key parameters:
- serves noVNC static files
- Port 6080 is the WebSocket endpoint
- Target is the VNC port (5901 for display :1)
Phase 4: Boot Verification
This is the most commonly failed step. Never assume boot succeeded based on process status alone.
Verification strategies:
- QMP display query: Send
{"execute": "query-status"}
to check VM state
- VNC screenshot: Use or similar to capture current display
- QMP screendump:
{"execute": "screendump", "arguments": {"filename": "/tmp/screen.ppm"}}
- Connect via VNC client: Actually view the display, not just test connectivity
Boot timing considerations:
- Legacy OS may need user interaction to complete boot (pressing Enter, clicking OK)
- Implement polling rather than fixed sleep delays
- Consider boot sequence: BIOS → DOS → Windows (multiple stages)
Phase 5: Input Verification
After establishing QMP connection:
- Send test keystrokes and verify display changes
- Each QMP connection requires capability negotiation first:
json
{"execute": "qmp_capabilities"}
- Then send keys:
json
{"execute": "send-key", "arguments": {"keys": [{"type": "qcode", "data": "ret"}]}}
Common Pitfalls
QEMU Version Compatibility
If task specifies "compatible with QEMU X.Y.Z" but a different version is installed:
- Document the version mismatch
- Test if the image actually boots with the available version
- Report any compatibility issues observed
nginx Configuration Conflicts
Symptoms: 502 Bad Gateway, connection refused
Prevention:
- Always audit existing nginx config before adding new server blocks
- Check for conflicting directives
- Verify upstream (websockify) is running before nginx tries to proxy to it
Premature Task Completion
Never mark "VM booted successfully" without:
- Visual confirmation (screenshot or VNC connection)
- Or QMP state verification showing expected state
QMP Socket Issues
- Stale socket files from previous runs cause connection failures
- Always clean up or equivalent before starting QEMU
- Use or to test socket connectivity
Boot Detection
Arbitrary
commands are unreliable. Instead:
- Poll QMP status at intervals
- Check for specific display content changes
- Implement timeout with failure handling
Verification Checklist
Before declaring task complete:
Resources
references/
Refer to
references/qemu_legacy_os.md
for detailed QEMU flags and compatibility notes for legacy operating systems.
Refer to
references/novnc_nginx_config.md
for production-ready nginx configuration templates.