-
Notifications
You must be signed in to change notification settings - Fork 113
Enable System Emulation in Web Browsers #602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Marked as draft since separating the deployment of user and system emulation for WebAssembly may require further discussion. If we all agree to proceed with the separation,, a similar repo like rv32emu-demo (might be called |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmarks
Benchmark suite | Current: 05924ce | Previous: 1f72e2b | Ratio |
---|---|---|---|
Dhrystone |
1272 Average DMIPS over 10 runs |
1273 Average DMIPS over 10 runs |
1.00 |
Coremark |
922.357 Average iterations/sec over 10 runs |
903.084 Average iterations/sec over 10 runs |
0.98 |
This comment was automatically generated by workflow using github-action-benchmark.
Can the system emulation be part of |
Yes, we can. Take this as an example: https://chinyikming.github.io/rv32emu-demo/ for user space emulation, and https://chinyikming.github.io/rv32emu-demo/system for system emulation. |
src/emulate.c
Outdated
@@ -1003,12 +1003,19 @@ static bool rv_has_plic_trap(riscv_t *rv) | |||
(rv->csr_sip & rv->csr_sie)); | |||
} | |||
|
|||
#if defined(__EMSCRIPTEN__) | |||
extern bool is_input_buf_avail; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a more appropriate header where this extern
declaration could be placed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a more appropriate header where this
extern
declaration could be placed?
Introduce src/emsc.h
for the concern.
Bito Automatic Review Skipped - Draft PR |
1 similar comment
Bito Automatic Review Skipped - Draft PR |
The index page of the demo links have been updated. Both user-space and system emulation can now be navigated back and forth using the newly added navigation buttons. |
User-space emulation has been supported and deployable in WebAssembly since sysprog21#389, but system emulation was not yet available. With sysprog21#508, system emulation was introduced, and later sysprog21#551 added support for trap-and-emulate of guest Linux SDL syscalls, enabling offloading to the host’s SDL backend. This commit bridges these components together to enable full system emulation in the browser. xterm.js is leveraged as the frontend terminal, bridged with the backend VM shell through a custom buffer management mechanism. This mechanism handles both standard ASCII input and escape sequences (such as arrow keys), providing a shell experience in the browser that closely resembles a real terminal. To handle terminal input without blocking the browser’s cooperative multitasking model, the original approach of mapping the read() system call to window.prompt() is avoided. Blocking behavior would freeze the browser’s event loop and degrade responsiveness. Instead, input from xterm.js is stored in a shared input buffer. The rv32emu periodically checks this buffer when handling external interrupts, and if input is available, it is read and consumed by the guest OS shell. The SDL graphic and sound backend are also supported. After booting the guest Linux system, users can run graphical applications such as doom-riscv, quake, or smolnes. These programs can be exited using Ctrl+C or their built-in exit funtionality. To reduce the size of the WebAssembly build and for the sake of the modularity, the project is now separated into user and system targets. As a result, two dedicated HTML files and corresponding preload JavaScript files are introduced: - user.html with user-pre.js - system.html with system-pre.js Navigation buttons are added to the index pages of both user and system demos, allowing users to switch easily between the two modes. Note that these navigation buttons are only functional when both user and system demos are deployed together, otherwise, the target pages may not be reachable. To improve usability, logic is implemented to disable and enable the "Run" button at appropriate times, preventing accidental re-execution when the process is already running. Additional improvements: - Ensure xterm.js uses \r\n instead of \n when logging to correctly move the cursor to the beginning of the line. - Add a new src/emsc.h header to store Emscripten-related variables and function declarations for better management. This implementation has been tested on the latest versions of Chrome, Firefox, and Safari. To serve user space emulation index page: $ make start-web CC=emcc ENABLE_SDL=1 -j8 To serve system emulation index page: $ make start-web CC=emcc ENABLE_SYSTEM=1 ENABLE_SDL=1 INITRD_SIZE=32 -j8
This commit updates the CI to deploy both user and system WebAssembly demos to the rv32emu-demo repository, resulting in the following file structure: . |-- coi-serviceworker.min.js |-- elf_list.js |-- index.html |-- rv32emu.js |-- rv32emu.wasm |-- rv32emu.worker.js |-- system |-- coi-serviceworker.min.js |-- index.html |-- rv32emu.js |-- rv32emu.wasm |-- rv32emu.worker.js The top-level files serve the user-space demo, while the system/ subdirectory hosts the system emulation demo. This structure allows both pages to coexist and be navigated independently in the same deployment. Improvements: - The release artifacts in the rv32emu-prebuilt repository include either a user-space executable (e.g., RISC-V ELF binaries) or a Linux image for system emulation. To distinguish between these two types of releases and trigger only the necessary deployment workflow, two separate dispatch event types are introduced: - deploy_user_wasm for user-space emulation WebAssembly deployment. - deploy_system_wasm for system emulation WebAssembly deployment. - Add needs and always() to ensure proper sequencing and execution of dependent jobs when both targets are deployed. - Change the source of the shareware Doom artifact: Downloading directly from the original site often results in 403 Forbidden errors on GitHub runners recently. The artifact is now hosted in our own repository (rv32emu-prebuilt) for more reliable access. Error: Resolving www.doomworld.com (www.doomworld.com)... 172.67.171.63, 104.21.29.17, 2606:4700:3037::ac43:ab3f, ... Connecting to www.doomworld.com (www.doomworld.com)|172.67.171.63|:443... connected. HTTP request sent, awaiting response... 403 Forbidden
Without this, the ELF list may be generated incorrectly because the build/riscv32 ELF executable has not been fetched yet.
Demo Link
link. Press 'Run Linux' button to boot Linux. After booting, use it as usual. Experience graphics and sounds by running doom-riscv, quake, smolnes.
Demo Video
system-emu-wasm.mp4
Description
User-space emulation has been supported and deployable in WebAssembly
since #389, but system emulation was not yet available. With #508,
system emulation was introduced, and later #551 added support for
trap-and-emulate of guest Linux SDL syscalls, enabling offloading to the
host’s SDL backend. This commit bridges these components together to
enable full system emulation in the browser.
xterm.js is leveraged as the frontend terminal, bridged with the backend
VM shell through a custom buffer management mechanism. This mechanism
handles both standard ASCII input and escape sequences (such as arrow
keys), providing a shell experience in the browser that closely
resembles a real terminal.
To handle terminal input without blocking the browser’s cooperative
multitasking model, the original approach of mapping the read()
system call to window.prompt() is avoided. Blocking behavior would
freeze the browser’s event loop and degrade responsiveness. Instead,
input from xterm.js is stored in a shared input buffer. The rv32emu
periodically checks this buffer when handling external interrupts, and
if input is available, it is read and consumed by the guest OS shell.
The SDL graphic and sound backend are also supported. After booting the
guest Linux system, users can run graphical applications such as
doom-riscv, quake, or smolnes. These programs can be exited using
Ctrl+C or their built-in exit funtionality.
To reduce the size of the WebAssembly build and for the sake of the
modularity, the project is now separated into user and system targets.
As a result, two dedicated HTML files and corresponding preload
JavaScript files are introduced:
Navigation buttons are added to the index pages of both user and system
demos, allowing users to switch easily between the two modes.
Note that these navigation buttons are only functional when both user
and system demos are deployed together, otherwise, the target pages may
not be reachable.
To improve usability, logic is implemented to disable and enable the
"Run" button at appropriate times, preventing accidental re-execution
when the process is already running.
Additional improvements:
the cursor to the beginning of the line.
function declarations for better management.
This implementation has been tested on the latest versions of Chrome,
Firefox, and Safari.
Updates the CI to deploy both user and system WebAssembly
demos to the rv32emu-demo repository, resulting in the following file
structure:
The top-level files serve the user-space demo, while the system/
subdirectory hosts the system emulation demo. This structure allows both
pages to coexist and be navigated independently in the same deployment.
Improvements:
either a user-space executable (e.g., RISC-V ELF binaries) or a Linux
image for system emulation. To distinguish between these two types of
releases and trigger only the necessary deployment workflow, two
separate dispatch event types are introduced:
dependent jobs when both targets are deployed.
Downloading directly from the original site often results in 403
Forbidden errors on GitHub runners recently. The artifact is now
hosted in our own repository (rv32emu-prebuilt) for more reliable
access. Error:
Resolving www.doomworld.com (www.doomworld.com)... 172.67.171.63, 104.21.29.17, 2606:4700:3037::ac43:ab3f, ...
Connecting to www.doomworld.com (www.doomworld.com)|172.67.171.63|:443%7C172.67.171.63%7C:443/)... connected.
HTTP request sent, awaiting response... 403 Forbidden
Reproduce
3.1 To serve user space emulation index page:
3.2 To serve system emulation index page:
Once the server is running, open your browser (Chrome, Firefox, or Safari) and navigate to
http://127.0.0.1:8000/
to test it. The expected result should match link.Summary by Bito
This pull request enhances system emulation in web browsers using WebAssembly, allowing users to run Linux and graphical applications like doom-riscv and quake. It introduces a new HTML interface for terminal interaction, improves memory management, and restructures the build process to separate user and system targets for better modularity.