copy / v86

x86 PC emulator and x86-to-wasm JIT, running in the browser
https://copy.sh/v86/
BSD 2-Clause "Simplified" License
19.59k stars 1.36k forks source link

Endless black screen loading from large .img file when selfhosting, no issues manually loading on website #1089

Closed HunterBoy344 closed 1 month ago

HunterBoy344 commented 1 month ago

My code:

<title>Basic Emulator</title><!-- not BASIC! -->

<style>
  html, body {margin: 0; height: 100%; width: 100%; overflow: hidden; background: black; position:relative; line-height: 1;}
  #screen_container {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: black;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  #vga {
    object-fit: contain;
    display: block;
    height: 100vh !important;
    width: auto !important;
    max-width: 100vw !important;
    border: solid 1px white;
  }
  * { margin:0; padding:0; }
</style>

<script src="libv86.js"></script>
<script>
"use strict";

window.onload = function()
{
    var emulator = window.emulator = new V86Starter({
        wasm_path: "v86.wasm",
        memory_size: 256 * 1024 * 1024,
        vga_memory_size: 8 * 1024 * 1024,
        screen_container: document.getElementById("screen_container"),
        bios: {
            url: "seabios.bin",
        },
        vga_bios: {
            url: "vgabios.bin",
        },
        hda: {
            url: "image.img",
            //async: true,
            //size: 3 * 1024 * 1024 * 1024,
        },
        acpi: false,
        network_relay_url: "wss://relay.widgetry.org/",
        autostart: true,
    });
    document.getElementById("screen_container").onclick = function()
    {
        emulator.lock_mouse();
    };
}
</script>

<!-- A minimal structure for the ScreenAdapter defined in browser/screen.js -->
<div id="screen_container" style="">
    <div id="screen"></div>
    <canvas id="vga"></canvas>
</div>

This results in an endless black screen. I'm hosting it with python3 -m http.server in the directory with all the files.

In the folder this runs from, there is an index.html, libv86.js, seabios.bin, vgabios.bin, v86.wasm, and of course image.img. The image file is 3 GB total. Uncommenting the lines about async does cause seabios to run, but the python webserver gives an error ending with ConnectionResetError: [Errno 104] Connection reset by peer and seabios says Boot failed: could not read the boot disk and fails to boot.

Notably, my problem is remarkably similar to this one, with the only difference being that he got this result with a large state file and I'm getting it with a large disk image.

SuperMaxusa commented 1 month ago

https://github.com/copy/v86/blob/5435c2f8c428b587ad78d37a649580a7cb75fed0/docs/windows-xp.md?plain=1#L58-L63

HunterBoy344 commented 1 month ago

Ok, I understand that part, but ideally I’d prefer not to use async. I just included the async bit to show that it does, in fact, load seabios if async is enabled.

copy commented 1 month ago

When you use async: false, v86 will load the entire file in a single xhr request, and use the resulting ArrayBuffer as the storage. ArrayBuffers are limited to 2GB in some browsers (https://stackoverflow.com/a/72124984).

We could handle this case transparently (by loading the file in 1GB chunks, or streaming downloads), but it's not clear that this is really useful (loading entire 3GB at once). If you want to improve disk speed, I'd suggest using async: true, use_parts: true, fixed_chunk_size: 1024 * 1024.

In any case, I will improve the code to print a useful error in this situation.

copy commented 1 month ago

The async: true case works fine for me, could use libv86-debug.js and check if there are any messages in the browser console?