v86 x86 Emulator

repository·master·Indexed 12 days ago

https://github.com/copy/v86

An x86-compatible CPU and hardware emulator that runs in the browser via WebAssembly. It emulates a Pentium 4 level instruction set with SSE3 support, allowing developers to run entire operating systems like Linux, Windows, or FreeDOS directly in a web page. Features include support for VGA graphics, NE2000 networking, and various virtio devices.

Tokens
28K
Snippets
90
Records
146
Agent score
98%

What's inside v86

  1. CPU idling support in Windows 98+ and Unix-like systems

    master
    Windows 98 and newer versions, as well as Unix-like operating systems, natively support the hlt instruction. No additional configuration or software is required to prevent CPU spin looping.
  2. What is v86 and its hardware capabilities?

    master

    v86 is an x86-compatible CPU and hardware emulator that uses WebAssembly to achieve performance in the browser. It emulates a Pentium 4 level instruction set with full SSE3 support.

    Emulated Hardware:

    • CPU: x86-compatible (Pentium 4 level, SSE3). Note: Lacks multicore, 64-bit extensions, task gates, and some 16-bit protected mode features.
    • FPU: Uses Berkeley SoftFloat for precision.
    • Controllers: 8272A Floppy, 8042 Keyboard (PS2 with mouse), 8254 PIT, 8259 PIC (partial APIC support), CMOS RTC, IDE disk controller, and a built-in ISO 9660 CD-ROM generator.
    • Graphics: Generic VGA with SVGA and Bochs VBE Extensions.
    • Networking: NE2000 (RTL8390) PCI card and various virtio devices (Filesystem, network, balloon).
    • Other: PCI bus, SoundBlaster 16, and a Hayes-compatible dial-up Modem.
  3. Compare v86 network backends

    master

    v86 supports several network backends that operate at different layers of the TCP/IP model. The choice of backend determines the level of virtualization and the type of network access available to the guest:

    • inbrowser: Operates at the Data Link/Network layer using the BroadcastChannel API. It allows multiple v86 guests in the same browser process (same page or different tabs) to communicate with each other. It is highly efficient but provides no access to external networks.
    • wsproxy: Operates at the Data Link/Network layer using WebSockets. It provides raw ethernet services and typically connects guests to a separate IP subnet via a proxy server, often providing access to the physical network or Internet.
    • wisp: Operates at the Transport layer. It wraps TCP/UDP payloads into WISP messages. It is designed for client/server communication over WebSockets. Note that guests are isolated from each other.
    • fetch: Operates at the Application layer using the browser's fetch() API. It allows guests to make HTTP requests to external servers. It handles DHCP/ARP internally and is useful when CORS is not an issue, though a CORS proxy may be required for general Internet access.
  4. Dial WebSocket addresses using Dial commands

    master

    The Modem translates dial addresses into WebSocket addresses using the following priority:

    1. Phonebook: Matches the address against the phonebook config.
    2. IPv4/Port: Translates dotted-IP:Port or zero-padded IP/Port (12-17 digits) into a WebSocket address.
    3. Direct: Uses the string directly as a WebSocket address.

    If the resulting address does not start with ws:// or wss://, the prefix is added based on the current dial mode (ws:// for pulse, wss:// for tone).

    Dial Command Syntax

    • D "<dial-address>" [;] : Dial using preset method (default: pulse).
    • DP "<dial-address>" [;] : Dial using pulse dialling (ws://).
    • DT "<dial-address>" [;] : Dial using tone dialling (wss://).

    Note: Use quotes if the address starts with P, T, p, or t.

    # Examples assuming phonebook {"911": "ws://example.com:56789"}
    
    AT D 111.22.3.44:56789      # Dotted-IP
    AT D 111-22-3-44-56789      # Separator variation
    AT D example.com:56789     # Hostname
    AT D "example.com:56789"    # Quoted hostname
    AT D ws://example.com:56789 # Explicit protocol
    AT DP ws://111.22.3.44:56789 # Explicit pulse
    AT DT ws://111.22.3.44:56789 # Explicit tone (overrides DT prefix)
    AT D 11102200304456789      # Zero-padded IP
    AT D 911                     # Phonebook match
  5. How v86 networking works

    master

    Networking in v86 consists of two primary components:

    1. NIC Emulation: The virtual Network Interface Controller provided to the guest OS. v86 supports two types:
      • ne2k: An NE2000/RTL8390-compatible NIC. Use this for older operating systems like FreeDOS.
      • virtio: A VirtIO-compatible device. This is recommended for modern operating systems. If the guest OS supports both, try virtio first.
    2. Network Backend: The mechanism that passes ethernet frames between the virtual NIC and a virtual or physical ethernet network. Backends vary in their level of network access and may require specific proxy servers.
  6. Boot Arch Linux via 9p Network Filesystem

    master

    Booting via the 9p network filesystem allows v86 to load files on-demand via HTTP requests. This enables near-instant startup when combined with a saved state, as only the necessary files are fetched over the network.

    Requirements for 9p Booting:

    1. Image Generation: The image must be converted into a JSON filesystem mapping using fs2json.py.
    2. Kernel Modules: The guest kernel must include atkbd, i8042, 9p, 9pnet, 9pnet_virtio, fscache, and netfs in its MODULES array.
    3. Initcpio Hook: A custom 9p_root hook must be added to initcpio to remount the root filesystem using the host9p device.
    4. v86 Configuration: Use the filesystem and bzimage_initrd_from_filesystem keys in the V86 configuration.

    v86 Configuration Example:

    {
      filesystem: {
        baseurl: "../output/images/arch/",
        basefs: "../output/images/fs.json",
      },
      bzimage_initrd_from_filesystem: true,
      cmdline: [
        "rw",
        "root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose",
      ].join(" "),
      acpi: false,
      autostart: true,
    }
    filesystem: {
      baseurl: "../output/images/arch/",
      basefs: "../output/images/fs.json",
    },
    
    bzimage_initrd_from_filesystem: true,
    
    cmdline: [
      "rw",
      "root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose",
    ].join(" "),
    
    acpi: false,
    autostart: true,
  7. Use AT commands with the v86 Modem

    master

    The v86 Modem implements a V.250-compatible command-line interpreter. Commands are case-insensitive and follow the syntax:

    AT <CMD>[<ARG>] [<CMD>[<ARG>] ...] <CR>

    Command Syntax Rules

    • <CMD>: One or more non-numerical characters.
    • <ARG>: An optional sequence of digits (except for Dial and S-Register commands).
    • Whitespace: Ignored.
    • Termination: Commands A, D, H, Z, and &F terminate the command line. Other commands can be combined.
    • Length: Maximum command line length is 256 characters.
    • Online/Offline: If a dial command ends with a semicolon (;), the Modem stays in AT command mode after completion. Otherwise, it switches to online data mode.
  8. Build an Alpine Linux 9p image using Docker

    master

    To build a custom Alpine Linux 9p image for use with v86, follow these steps:

    1. Customize the image: Edit the Dockerfile to select your preferred kernel flavor (e.g., virt for a smaller image vs lts) and to add any additional packages you require. The community repository is enabled by default.
    2. Build the image: Ensure a Docker daemon (or Podman) is running, then execute the build script:
      ./build.sh
    3. Run and verify: Start a local webserver (for example, using make run) and navigate to examples/alpine.html in your browser to see the image in action.
    4. Set initial state (optional): To load a specific state, run ./build-state.js and update your alpine.html file to include the generated state URL in the configuration:
      initial_state: { url: "../images/alpine-state.bin.zst" }
    ./build.sh
  9. Enable CPU idling in MS-DOS using DOSIdle

    master

    If your MS-DOS guest is spin-looping instead of idling, you can use DOSIdle to enable hlt instruction support.

    1. Download DOSID251.zip from Vogons.
    2. Unzip DOSIDLE.EXE to a location on your C: drive (e.g., C:\DOSIDLE.EXE).
    3. Edit your C:\autoexec.bat file.
    4. Add the path to the executable to the file. To prevent the tool from printing output to the console during startup, redirect the output to nul.
    5. Save the changes and restart the VM.
    C:\path\to\dosidle.exe > nul
  10. Install and run Windows NT 4.0 in v86

    master

    Installation via QEMU

    Run QEMU with these settings:

    qemu-system-i386 -m 64 -drive file=hdd.img,format=raw -cdrom InstallCD.iso -cpu pentium -M pc,acpi=off

    During setup startup, press F5 and select Standard PC.

    Running in v86

    To avoid CPUID issues when running Windows NT 4.0 in the v86 emulator, you must configure the constructor with cpuid_level: 2 and acpi: false. Note that these options are not supported via the standard UI.

    var emulator = new V86({
        ... 
        cpuid_level: 2,
        acpi: false
    });
  11. Install Windows NT 3.51 and enable networking

    master

    Installation

    If installing via MS-DOS, use the Oak CD-ROM Driver and run <CD-ROM letter>:\I386\WINNT /B.

    Note: If setup fails in newer QEMU versions, try older versions like PCem, 86Box, or PCBox.

    After installation, you can apply the NT 3.51 SuperPack by copying files from the FAT32 (SYS\FAT32) and RENEW (SYS\RENEW) folders into C:\WINNT35\system32\drivers (replacing existing files).

    Enabling Networking

    1. Open Control Panel > Network and install Windows NT Networking (requires installation CD).
    2. In Network Adapter Card Detection, press Continue three times and set Network Adapter Card: Novell NE2000 Compatible Adapter.
    3. Use these settings:
      • IRQ Level: 10
      • I/O Port Address: 0x300
    4. In Bus Location, press OK. Check TCP/IP Transport and Enable Automatic DHCP Configuration.
    5. In TCP/IP Configuration, ensure Enable Automatic DHCP Configuration is checked.
    6. Restart the VM.