V86 - x86 virtualization in your browser, recompiling x86 to wasm on the fly

Overview

Join the chat at https://gitter.im/copy/v86

v86 emulates an x86-compatible CPU and hardware. Machine code is translated to WebAssembly modules at runtime in order to achieve decent performance. Here's a list of emulated hardware:

  • An x86-compatible CPU. The instruction set is around Pentium III level, including full SSE2 support. Some features are missing, in particular:
    • Task gates, far calls in protected mode
    • Some 16 bit protected mode features
    • Single stepping (trap flag, debug registers)
    • Some exceptions, especially floating point and SSE
    • Multicore
    • PAE
    • 64-bit extensions
  • A floating point unit (FPU). Calculations are done using the Berkeley SoftFloat library and therefore should be precise (but slow). Trigonometric and log functions are emulated using 64-bit floats and may be less precise. Not all FPU exceptions are supported.
  • A floppy disk controller (8272A).
  • An 8042 Keyboard Controller, PS2. With mouse support.
  • An 8254 Programmable Interval Timer (PIT).
  • An 8259 Programmable Interrupt Controller (PIC).
  • Partial APIC support.
  • A CMOS Real Time Clock (RTC).
  • A generic VGA card with SVGA support and Bochs VBE Extensions.
  • A PCI bus. This one is partly incomplete and not used by every device.
  • An IDE disk controller.
  • An NE2000 (8390) PCI network card.
  • A virtio filesystem.
  • A SoundBlaster 16 sound card.

Demos

Arch LinuxDamn Small LinuxBuildroot LinuxReactOSWindows 2000Windows 98Windows 95Windows 1.01MS-DOSFreeDOSFreeBSDOpenBSD9frontHaikuOberonKolibriOSQNX

Compatibility

Here's an overview of the operating systems supported in v86:

  • Linux works pretty well. Neither 64-bit nor PAE kernels are supported.
    • Damn Small Linux (2.4 Kernel) works.
    • All tested versions of TinyCore work.
    • BuildRoot can be used to build a minimal image. humphd/browser-vm has some useful scripts for building one.
    • Archlinux works. See archlinux.md for building an image.
    • Debian works. An image can be built from a Dockerfile, see tools/docker/debian/.
    • Ubuntu up to 10.04 works.
    • Alpine Linux works.
  • ReactOS works.
  • FreeDOS, Windows 1.01 and MS-DOS run very well.
  • KolibriOS works.
  • Haiku works.
  • Android x86 1.6-r2 works if one selects VESA mode at the boot prompt. Newer versions may work if compiled without SSE3. See #224.
  • Windows 1, 3.0, 95, 98, ME and 2000 work. Other versions currently don't (see #86, #208).
    • In Windows 2000 and higher the PC type has to be changed from ACPI PC to Standard PC
  • Many hobby operating systems work.
  • 9front works.
  • Plan 9 doesn't work.
  • QNX works.
  • OS/2 doesn't work.
  • FreeBSD works.
  • OpenBSD works with a specific boot configuration. At the boot> prompt type boot -c, then at the UKC> prompt disable mpbios and exit.
  • NetBSD works only with a custom kernel, see #350.
  • SerenityOS doesn't work due to missing PAE support.

You can get some infos on the disk images here: https://github.com/copy/images.

How to build, run and embed?

You need:

  • make
  • Rust with the wasm32-unknown-unknown target
  • A version of clang compatible with Rust
  • java (for Closure Compiler, not necessary when using debug.html)
  • nodejs (a recent version is required, v16.11.1 is known to be working)
  • To run tests: nasm, gdb, qemu-system, gcc, libc-i386 and rustfmt

See tools/docker/test-image/Dockerfile for a full setup on Debian or WSL.

  • Run make to build the debug build (at debug.html).
  • Run make all to build the optimized build (at index.html).
  • ROM and disk images are loaded via XHR, so if you want to try out index.html locally, make sure to serve it from a local webserver. You can use make run to serve the files using Python's http module.
  • If you only want to embed v86 in a webpage you can use libv86.js. For usage, check out the examples. You can download it from the release section.

Alternatively, to build using docker

  • If you have docker installed, you can run the whole system inside a container.
  • See tools/docker/exec to find Dockerfile required for this.
  • You can run docker build -f tools/docker/exec/Dockerfile -t v86:alpine-3.14 . from the root directory to generate docker image.
  • Then you can simply run docker run -it -p 8000:8000 v86:alpine-3.14 to start the server.
  • Check localhost:8000 for hosted server.

Testing

The disk images for testing are not included in this repository. You can download them directly from the website using:

wget -P images/ https://k.copy.sh/{linux.iso,linux4.iso,buildroot-bzimage.bin,openbsd-floppy.img,kolibri.img,windows101.img,os8.img,freedos722.img}

Run all tests: make jshint rustfmt kvm-unit-test nasmtests nasmtests-force-jit expect-tests jitpagingtests qemutests rust-test tests

See tests/Readme.md for more infos.

API examples

Using v86 for your own purposes is as easy as:

var emulator = new V86Starter({
    screen_container: document.getElementById("screen_container"),
    bios: {
        url: "../../bios/seabios.bin",
    },
    vga_bios: {
        url: "../../bios/vgabios.bin",
    },
    cdrom: {
        url: "../../images/linux.iso",
    },
    autostart: true,
});

See starter.js.

License

v86 is distributed under the terms of the Simplified BSD License, see LICENSE. The following third-party dependencies are included in the repository under their own licenses:

Credits

More questions?

Shoot me an email to [email protected]. Please report bugs on GitHub.

Author

Fabian Hemmer (https://copy.sh/, [email protected])

Comments
  • Implement VGA graphical behaviour on per-register basis

    Implement VGA graphical behaviour on per-register basis

    This package contains the following goodness

    • VGA write modes 0, 1, 2, 3 with set/reset, planar rotation.
    • VGA write using single dword to represent all 4 plane bytes.
    • VGA read mode 1.
    • Provides a workaround solution to issues #110 and #90 (sacrificing the performance and resolution of the vbe driver for normal vga)

    Update: this PR now also includes:

    • VGA chain odd/even and interleaved shift - implements modes 4h and 5h.
    • VGA unchained, chain 4 256 color shift - implements modes 13h, mode X.
    • VGA panning, page flipping, split screen.
    • VGA palette redraws.

    Demo

    (This is the same video as the one for sb16 PR)

    https://drive.google.com/file/d/1FSt14j7ayKnaT7AS8lF_4S1i4ZX9GlEk/view (the demo also contains code for 320x400 display mode that is not included with this PR)

    Notes

    • I'm curious to see if you like how the modes are implemented here. The calculations (bitmasks, ALU, etc.) got moved out from inside vga_memory_write_graphical_planar into their own, separate functions. This way, ~~the code looks more beautiful and satisfies my OCD~~ the circuitry intentions for each mode is much clearer. I'm not sure about the performance aspects though (I haven't profiled them yet).

    Todo

    • [x] Find a way to test out each mode. So far, I've only tested by booting up Windows 98 with VBE drivers removed, which worked well even before read mode 1 was implemented.
    • [x] Test with Windows 98: windows, screen savers, paint, solitaire
    • [x] Test some of Michael Abrash's Graphics Programming Black Book sample code
    • [x] Test some DOS games on the write modes
    • [x] Merge routines for mode 12h and 13h into single function.
    • [x] Implement unchained 256 color shift
    • [x] Implement odd/even chain and interleaved shift
    • [x] Implement page flipping, panning, and split screens
    • [x] Try out using linked lists to keep track of what pixels use what color, so when the palette changes the pixels can be updated
    • [x] Fix the svga and text mode regressions on other OSes
    • [x] Fix / optimize / consider keeping or removing the linked list.
    • [x] Add new states to get_state and set_state functions.
    opened by ErnWong 33
  • Progress on Running Android-x86

    Progress on Running Android-x86

    It is clearly indicated in the readme -"No Android version seems to work, you still get a shell."- that Android doesn't run on v86, yet.

    I wanted to submit a new issue for tracking the progress of running Android-x86 on v86, to share with each other

    • why it doesn't run
    • what can be done
    • what is being worked on and by whom

    This is especially interesting/exciting since if we manage that, we can run Android as a progressive webapp (PWA) on Mobile Safari on iPhone and iPad; not that it will be necessarily useful but surely fun! =)

    guest-os-support 
    opened by boramalper 32
  • Provide bootable image with 9p support

    Provide bootable image with 9p support

    I want to use the 9p filesystem and inject files into it. To inject files, I need to get the emulator instance. The Arch Linux demo is, AFAIK, the only one that features 9p support, however, it only works with the production build, which uses the closure compiler, which means I cannot get the emulator instance (since I don't know how it was mangled).

    I can also build the image myself, maybe you have recommendations on how to do this? I imagine that I only need to build a new kernel, since I can use the userland from ttylinux or the linux26 image.

    opened by ysangkok 25
  • SectorLISP appears to hang after

    SectorLISP appears to hang after "Booting from Floppy..."

    does not seem to move past this point, also broken when using latest sectorlisp.bin from https://github.com/jart/sectorlisp/blob/040852302c1bd37b16bfb8f123083b80c07fd0be/bin/sectorlisp.bin stuck

    opened by foxsouns 19
  • readme: add SkiffOS (Buildroot) config link

    readme: add SkiffOS (Buildroot) config link

    SkiffOS is a configuration layering system for Buildroot.

    It supports re-targeting system image configs to different hardware.

    The linked configuration can be combined with other layers to deploy Docker and other Linux distributions to the v86 emulator.

    The configuration fragments slim down the Buildroot and Kernel systems & switch off any unnecessary features.

    https://github.com/skiffos/SkiffOS/tree/master/configs/browser/v86

    Demo ISO: https://drive.google.com/file/d/1UFoUEt1CQrD8B4800ii9yehff68h9IPG/view

    V86 is really awesome & I was really floored to see that everything could run in it with minimal adjustments.

    opened by paralin 17
  • Run the CPU in a web worker

    Run the CPU in a web worker

    The jor1k guys do this too: Run the CPU and devices code in a web worker, saving the time for rendering. For graphical modes, this requires a significant amount of data to be transferred between the worker and the window, so it might not actually be faster (needs to be researched).

    This requires some significant changes in the code, including some sort of abstraction between the code that will run in the worker and the code that will run in the window.

    enhancement 
    opened by copy 17
  • Boot SerenityOS

    Boot SerenityOS

    Pretty cool hobby OS: https://github.com/SerenityOS/serenity

    Requires hardware task switching support: https://github.com/SerenityOS/serenity/blob/7fc903b/Kernel/Scheduler.cpp#L574-L578

    guest-os-support 
    opened by copy 16
  • BSoD in Win2K Setup

    BSoD in Win2K Setup

    So I was in the middle of setting up Windows 2000, and before it could show drives to install Windows on, it got a BSoD. I retried, the same thing happened again. It has the error code "0x0000007B (0xF2463848,0xC0000034,0x00000000,0x00000000)" and says "INACCESSIBLE_BOOT_DEVICE". The ISO I have has worked in the past for every emulator I've used, and I even tried retrying it via VirtualBox & QEMU, the ISO works. I decided to try setting up Windows 2K since the furthest edition of Windows uploaded for the public was Windows 98, and I wanted to try something new as well. Capture

    guest-os-support 
    opened by ITAC85v2 16
  • Network support

    Network support

    Network support would be a nice feature. The jor1k project is already running this successfully.

    The emulated hardware could be ported from jsmodem (which is based on a UART, which we already have) or written from scratch. In the latter case, a network card that is supported by KolibriOS should be emulated.

    Some feature ideas:

    • Internet connection using websockets
    • Local connection between two VM instances
    • Connect on demand (i.e., start the websocket as soon as it's needed, not on boot)
    • Rate limit the connection
    enhancement 
    opened by copy 16
  • Can't get audio output except for a simple beep

    Can't get audio output except for a simple beep

    I can't figure out how to play audio from within a Linux env. I have testing building a Debian install with sox installed (Build scripts:https://git.sr.ht/~hamner/copyleftmage.school) Running example: http://copyleftmage.school/v86/live/shell_full_boot.html Relevant setup data:

    window.onload = function() {
        var emulator = new V86Starter({
            wasm_path: "../build/v86.wasm",
            memory_size: 512 * 1024 * 1024,
            vga_memory_size: 8 * 1024 * 1024,
            screen_container: document.getElementById("screen_container"),
            cmdline: "rw init=/bin/systemd root=host9p console=ttyS0 spectre_v2=off pti=off",
            bios: {
                url: "../bios/seabios.bin",
            },
            vga_bios: {
                url: "../bios/vgabios.bin",
            },
            filesystem: {
                baseurl: "/v86/output/images/debian-rootfs-flat/",
                basefs: "/v86/output/images/debian-fs.json",
            },
            autostart: true,
            bzimage_initrd_from_filesystem: true,
            cmdline: [
                "rw",
                "root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose",
                "init=/usr/bin/init-openrc",
            ].join(" "),
        });
    
    

    Running arecord -l shows no sounds cards found. Running beep plays a beep sound but also outputs no devices found. Options to change to tone don't work. My goal is the build this site out to be a teaching tool, and audio would be a big help.

    opened by ruapotato 15
  • Not gonna lie im lost at how to set this up.

    Not gonna lie im lost at how to set this up.

    So im trying to basically make a website that only has windows 98 for my midterm school project. I just dont understand how to first off get the files to work (without hosting them) and second how i would make it so that on startup it loads the windows 98 image. essentially im just wondering how to only take the windows 98 portion of this or at the very least get everything to work.

    opened by chrislightsaber 15
  • Haiku R1 Beta 4 hangs during boot

    Haiku R1 Beta 4 hangs during boot

    Last serial output is:

    Haiku revision: hrev56578+59, debug level: 1
    CPU: no microcode provided
    reserve_io_interrupt_vectors: reserved 2 vectors starting from 98
    CPU 0: type 0 family 15 extended_family 0 model 6 extended_model 0 stepping 3, string 'GenuineIntel'
    No CPU topology information available.
    CPU 0: apic id 0, package 0, core 0, smt 0
    CPU 0: features: fpu pse tsc msr pae cx8 sep pge cmov mmx fxsr sse sse2 popcnt rdrnd hypervisor erms 
    CPU 0: patch_level 0
    CPU: using TSC frequency from CPUID
    reserve_io_interrupt_vectors: reserved 16 vectors starting from 0
    using 32 bit paging (PAE not needed)
    mark_page_range_in_use(0x0, 0x100): start page is before free list
    mark_page_range_in_use(0x0, 0xa0): start page is before free list
    
    guest-os-support 
    opened by copy 1
  • Running Doom on v86

    Running Doom on v86

    Not an issue, just a small video to see how well Doom (no sound) runs on v86:

    https://user-images.githubusercontent.com/829885/210173802-6cbe43b3-ebab-4a27-a8c6-db01b5d41e45.mp4

    This is the 64MB hard disk with a very reduced FiwixOS 3.2 system: 64M.img.zip [^1]

    user: root
    pass: root
    

    [^1]: updated on 2-Jan-2023 - fixed a segfault when exiting Doom.

    opened by mikaku 6
  • Enhancement: add antiX as a demo distro

    Enhancement: add antiX as a demo distro

    I tested the antiX distro on copy v86, and it seems to work very well. It is an established lightweight distro based on Debian and comes in 32 and 64-bit versions. The "base" version seems to have reasonable functionality for use on copy v86. Would be nice if it was demo version so that users could then select antiX and install a few additional packages and then "save state" to be able to rapidly restart work in that distro in their browser.

    It would then be additionally useful if that demo antiX browser would be able to access the user's local filesystem (similar to how the ArchLinux demo distro does).

    Thanks for considering this request.

    opened by SugarRayLua 5
  • Save disk changes in nodejs

    Save disk changes in nodejs

    I request a feature for the node.js version for the modified hdd data to be able to save+load, that is store, on the physical maschine as a file. Is this possible to implement? Thank you.

    enhancement 
    opened by Atybot 0
Releases(latest)
  • latest(Nov 26, 2022)

    Bug Fixes

    • rare conditional jump with double fallthrough doesn't set eip correctly (Fabian)
    • mov sreg, reg triggers pf before ud (Fabian)

    Commits

    • 6524bbc: Use local for condition generation after shifts (Fabian)
    • 1588687: optimise flag generation after adc/sbb (Fabian)
    • allow overlapping strings, as long as they don't overlay within a page (Fabian)
    • baffa6c: generate code for pshufd (660F70) (Fabian)
    • correctly advertise the latest bochs version, and make it r/w (fix #768) (Fabian)
    • 625fdcd: generate slightly better code for ud2 (Fabian)
    • generate code for {66,}0f{c4,c5} (pinsrw, pextrw) (Fabian)
    • generate code for punpckldq (660f62) (Fabian)
    • generate code for sse moves (f20f1[01], 660f6e, f30f7e, 660fd6) (Fabian)
    • 6b91f91: test pushf manually (Fabian)
    • 69e8eaf: test mov reg, sreg manually (Fabian)
    • mask fpu eip for fsave (Fabian)
    • set high bits of 16-bit fields (Fabian)
    • don't print control characters (Fabian)
    • da08451: import recent kvm-unit-test changes (fixes incorrectly failing push es test) (Fabian)
    • 651d0d8: fix push sreg only touches 16 bits of the stack dword (Fabian)
    • af1cb6d: make some jit parameters configurable at runtime (Fabian)
    • compare entire bss (resize it to 8kB) (Fabian)
    • log less (Fabian)
    • 011c94e: Add fiwix (Fabian)
    • d1cf93e: Add redox (#301) (Fabian)
    Source code(tar.gz)
    Source code(zip)
    libv86.js(368.33 KB)
    v86-fallback.wasm(1.69 MB)
    v86.wasm(1.69 MB)
Build your own Riscv Emulator in Rust.

Rare: Rust A Riscv Emulator RISC-V 模拟器教程 This tutorial is based on Asami's excellent tutorial. Although the author haven't finished it, she have alrea

Sakya Demon 74 Jul 9, 2023
virtualization-rs provides the API of the Apple Virtualization.framework in Rust language.

virtualization-rs Rust bindings for Virtualization.framework virtualization-rs provides the API of the Apple Virtualization.framework in Rust language

suzu 44 Dec 31, 2022
Detect if code is running inside a virtual machine (x86 and x86-64 only).

inside-vm Detect if code is running inside a virtual machine. Only works on x86 and x86-64. How does it work Measure average cpu cycles when calling c

null 34 Oct 3, 2022
Rust API to the OS X Hypervisor framework for hardware-accelerated virtualization

hypervisor-rs hypervisor is a Rust library that taps into functionality that enables hardware-accelerated execution of virtual machines on OS X. It bi

Saurav Sachidanand 57 Dec 8, 2022
rust-browser-game but native and rendered with ncurses in C without the Browser

Spin-off of rust-browser-game-but-sdl but with ncurses Nothing much to say. Just see rust-browser-game-but-sdl and rust-browser-game. Quick Start $ ma

Tsoding 8 Apr 21, 2022
The Bloat-Free Browser Game in Rust but in C and not in a Browser

rust-browser-game but native and rendered with SDL in C without the Browser The original idea of rust-browser-game is that the game.wasm module is com

Tsoding 12 Sep 26, 2022
Rslide - A web service that allows you to move through multiple html pages in the browser like a slide, even without focusing on the app console or the browser. Currently only supports Windows.

rslide rslide is a web service that allows you to move through multiple html pages in the browser like a slide, even without focusing on the app conso

Jason Dongheng Lee 3 Jan 1, 2022
McFly - fly through your shell history

McFly - fly through your shell history McFly replaces your default ctrl-r shell history search with an intelligent search engine that takes into accou

Andrew Cantino 4.8k Jan 7, 2023
WASM wrapper of mozjpeg, ready for the browser

mozjpeg-wasm This library wraps mozjpeg-sys and exposes a few functions to perform decoding, encoding and simple transformation on JPEG images using m

Tommaso 25 Nov 17, 2022
2D real-time mutliplayer game in a browser. Showcase of the usability of wasm-peer crate.

Footballers Description 2D real-time multiplayer game in a browser. Players divided in two teams play a football match on field with two goal posts. G

null 10 Dec 22, 2022
Realtime audio processing / synthesis using Rust/WASM in the browser.

Rust Audio About This repo is my investigation into using Rust for creative audio coding on various platforms (e.g. desktop, web, etc.), but especiall

Austin Theriot 30 Jan 5, 2023
Basic first-person fly camera for the Bevy game engine

bevy_flycam A basic first-person fly camera for Bevy 0.4 Controls WASD to move horizontally SPACE to ascend LSHIFT to descend ESC to grab/release curs

Spencer Burris 85 Dec 23, 2022
Rust On the FLY completion for neovim

rofl.nvim Rust On the FLy completion engine for Neovim. Why Rust? It's 2021. I think the question you should be asking yourself is "Why NOT Rust?!?? (

TJ DeVries 63 Sep 25, 2022
This is a public snapshot of Fly's init code. It powers every Firecracker microvm we run for our users.

Fly Init This is a public snapshot of Fly's init code. It powers every Firecracker microvm we run for our users. It is Rust-based and we thought makin

fly.io 186 Dec 30, 2022
On-the-fly machine code executing from Deno

jit from js Execute raw machine code from JavaScript. I hope you know what you're doing :) const inst = new Uint8Array([0xC3]); // ret const noop = ji

Divy Srivastava 5 Apr 26, 2021
On the fly syntax checking for GNU Emacs

https://www.flycheck.org Modern on-the-fly syntax checking extension for GNU Emacs. Try it! For a more gentle introduction read the Installation instr

Flycheck 2.3k Dec 30, 2022
A CLI tool that converts videos to ASCII and displays them to the terminal on the fly

A CLI tool that converts videos to ASCII and displays them to the terminal on the fly

Luke T 19 Nov 15, 2022
Terminal UI for erhanbaris/smartcalc, a new way to do calculations on-the-fly

smartcalc-tui Terminal UI for erhanbaris/smartcalc, a new way to do calculations on-the-fly. From the README: Do your calculation on text based querie

Aaron Ross 12 Sep 14, 2022
Yellhole is a lightweight tumblelog which can run on e.g. fly.io for cheap.

Yellhole A Hole To Yell In Yellhole is a lightweight tumblelog which can run on e.g. fly.io for cheap. Features Runs on a single node. Use a CDN if yo

Coda Hale 8 Dec 15, 2022