WasmLinux title

WasmLinux Terminal:

(Please wait for / # prompt. If it doesn't appear, focus the terminal and hit Enter. See below for why...)

WasmLinux

GitHub / X (formerly Twitter) / (J) Blog article on Zenn


Here is WasmLinux, prototype of WebAssembly "native" Linux system.

Unlike existing Linux-on-Wasm solutions like WebVM(x86) or container2wasm(RISC-V, x86), WasmLinux does not use emulator of any existing CPU architecture, both userland and kernel.

This is composed with patched NOMMU Linux(LKL) + lightly patched Linux MUSL libc + lightly patched Busybox, compiled to Wasm (and processed with Wasm2c and compiled again with Emscripten, just for setjmp/longjmp)

We are working on native setjmp/longjmp implementation, just like WASI libc #467 so we can drop wasm2c usage in future.

Try it!

Click the terminal above, then say ls, then hit Enter twice

Currently the only app provided is BusyBox. You can do other things such as vi, dmesg, ifconfig lo up then ping 127.0.0.1 or even top. To get list of available commands, say busybox .

Why do we need to hit Enter twice? (Limitations)

WasmLinux has several unimplemented features. Namely;

Actually, WasmLinux kernel is just a Wasm executable that contains LKL (Linux kernel library -- Linux kernel as userland library) so there is no real "kernel-mode" code. We will eventually implement mmap or POSIX signal emulations on it but I don't think WasmLinux will become actual linux arch.

It stopped working suddenly! (Known issues)

To recover from hang, just reload this page. It does not have any persistent data.

Many things are broken since we don't have proper POSIX signal implementation yet. Incomplete list of bugs;

Seems nice, where is the SDK? (Roadmap)

Comming soon(TM). Current near-term roadmap is;

  1. Add support to run on native browser Wasm implementation(+ Wasm Exceptions) so we can drop wasm2c overhead on browser environment.
  2. Implement asynchronous signal delivery. (won't be able to interrupt usermode though.)
  3. Implement WebRTC based inter-browser and local system(using libdatachannel) VPN
  4. Implement C-WebGL and EGL/OpenGL ES bridge layer. More Web API C bindings to access local devices.
  5. Implement memory protection(without address translation) using static Wasm translation so we can implement real fork(2).
  6. Implement shared library support
  7. Define wasm32-linux ABI and provide SDK so users can add apps
and we aim to support full microcontroller(ARM etc) toolchain + CMake + LLDB on the web. Self hosting would be nice to have but I think it would hard to be practical since current WasmLinux is in 32bit.

Long-term goal is to support mmap(2) with address translation (like v86) but I'm not really sure when it is ready.

PC(native) builds with wasm2c will remain as Tier1 platform of WasmLinux. PC builds will be the only way to implement "hardmmu" memory management.

Where can I find the sources? (Build)

Currently, it is just a PoC state thus sources are just complete mess; do not waste your time on it...

For reference, build flow overview:

Source/Build flow overview

Every source code reference is submoduled on GitHub wasmlinux-project repository.

Tentative syscall protocol is baked in Musl patches and implemented in runner source. It is just a Wasm export and will get final names elsewhere. User code should not call the export directly and encouraged to use libc.

On user's syscall, runner will call kernel through its wasm export that is exported from the kernel. Currently, wasm2c is the only Wasm engine that the runner support. Runner has knowledge of syscall argument counts and will adjust syscall argument when required -- calling C function with correct argument count is strict requirement of Wasm.

The runner has "pseudo inetd" feature that invokes a process on incomming connection and relay socket pair I/O to the host system. Host I/O backend is abstructed to miniio library and on PC build, it will use libuv. On browser build, it has dedicated localhost-only stub which is implemented on host pthread.

To communicate with WasmLinux system, BusyBox telnetd will be used. On PC build, conventional telnet client (e.g. PuTTY) will work. On browser build, our own minitelnet telnet client which is implemented on miniio will be used. Minitelnet assumes host environment supports Linux-like PTY and it is implemented using xterm-pty on this page.

Why? (Motivations)

Write once(by other folks), run anywhere(i want). I know we already have WASI or WALI, but unfortunately they need to be ported to some serious OS to work with. Since WasmLinux covers Linux kernel as well, required porting effort is quite little; it even have filesystems or device drivers. Even if you designed your own ISA just runs Wasm, WasmLinux (theoretically) easily ported on it and no need to port other apps that runs on WasmLinux.

... anyway, I think WALI still require apps to be ported to its environment because it doesn't provide enough platform abstraction to make porting effortless (e.g. page size is 64k, no setjmp/longjmp, ...). WasmLinux choose to develop native Linux Kernel that can be implemented on browser Wasm environments to ensure its ABI is enough portable.

Currently we can support BusyBox for almost zero porting effort, because it already supports NOMMU environment. We'd like to extend these to non-NOMMU apps by adding memory protection etc in future. Unfortunately many Linux apps assumes Linux environment is ELF, have computed gotos, have __builtin_return_address, assume implicit function pointer cast, etc. We believe WasmLinux solves some sort-of chicken/egg problem; some of these are good candidate for Wasm extension and existence of real apps would be helpful.

For now, entire WasmLinux system is just a usermode C++20 application; LKL and MUSL+BusyBox are ported on bare-bone Wasm environment then translated with wasm2c and linked with a thin runtime stub. We have intentionally avoided Emscripten for first porting to ensure ported WasmLinux kernel and apps can run on (mostly) standard WebAssembly engines, and wasm2c can turn it to plain C application. setjmp, longjmp and vfork are last remaining parts that require special Wasm engine capability but i think they can be implemented with Wasm exception proposal so we would be able to make entire system Emscripten-free eventually.

Credits

Terminal is implemented with xterm-pty. CSS is Water.css. Web page libraries are served by unpkg. Embedded telnet client is based on libtelnet.