# Webassembly on exotic architectures (a 2025 roundup)

*2025-04-16 — note*


It's about the time of the academic year to come up with project [ideas](/ideas)! [KC Sivaramakrishnan](https://kcsrk.info), [Andy Ray](https://github.com/andrewray) and I have been looking into [FPGA/OCaml matters](https://anil.recoil.org/notes/fpgas-hardcaml) recently so I thought I'd review the latest in the land of [Webassembly](https://webassembly.org) for non-traditional hardware targets.  It turns out that there are very fun systems projects going on to turn wasm into a "real" target architecture on several fronts: a native port of Linux to run in wasm, a port of wasm to run in kernel space, a POSIX mapping of wasm, and fledgling wasm-CPUs-on-FPGAs.


## Native port of Linux to wasm

The first one is a [_native_ port](https://github.com/tombl/linux) of the Linux kernel to run in webassembly ([try it in your browser](https://linux.tombl.dev)). This isn't an emulation; instead, the various kernel subsystems have been ported to have wasm interfaces, so the C kernel code runs directly as webassembly, with virtual device layers.

The inspiration for this seems to have come from a famous comment eight years ago on the LKML:

> One more general comment: I think this may well be the last new CPU architecture we ever add to the kernel. Both nds32 and c-sky are made by companies that also work on risc-v, and generally speaking risc-v seems to be killing off any of the minor licensable instruction set projects, just like ARM has mostly killed off the custom vendor-specific instruction sets already. If we add another architecture in the future, it may instead be something like the LLVM bitcode or WebAssembly, who knows?
> <cite>\-- [Arnd Bergmann, LKML, 2018](https://lore.kernel.org/all/CAK8P3a2-wyXxctVtJxniUoeShASMhF-6Z1vyvfBnr6wKJuioAQ@mail.gmail.com/)</cite>

And this port brings us much closer to that!  I need to spelunk more into the diffs to the mainline kernel to see how it all works, but some quick notes:

- the [tools/wasm](https://github.com/tombl/linux/blob/777d95246a8b1dc184e991a76946ccafef392206/tools/wasm/src/worker.ts) directory shows how some of the glue code works, such as the [worker.ts](https://github.com/tombl/linux/blob/777d95246a8b1dc184e991a76946ccafef392206/tools/wasm/src/worker.ts) which uses [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) to implement multicore, and the venerable [virtio](https://wiki.libvirt.org/Virtio.html) to implement [virtual block devices](https://github.com/tombl/linux/blob/wasm/tools/wasm/src/virtio.ts#L204).
- the [arch/wasm](https://github.com/tombl/linux/tree/777d95246a8b1dc184e991a76946ccafef392206/arch/wasm) contains the glue code, and [mm.c](https://github.com/tombl/linux/blob/777d95246a8b1dc184e991a76946ccafef392206/arch/wasm/kernel/irq.c#L17) shows how atomic builtins in wasm are sufficient to implement low-level memory management. The [clone](https://github.com/tombl/linux/blob/777d95246a8b1dc184e991a76946ccafef392206/arch/wasm/kernel/fork.c#L12C2-L12C24) implementation leads us to [wasm\_imports.h](https://github.com/tombl/linux/blob/777d95246a8b1dc184e991a76946ccafef392206/arch/wasm/include/asm/wasm_imports.h) which shows all the FFI stubs needed from the runtime in [worker.ts](https://github.com/tombl/linux/blob/777d95246a8b1dc184e991a76946ccafef392206/tools/wasm/src/wasm.ts#L21).  Notably, it looks like the [process switcher](https://github.com/tombl/linux/blob/777d95246a8b1dc184e991a76946ccafef392206/tools/wasm/src/worker.ts#L103) doesn't use the [wasm stack switching](https://github.com/WebAssembly/stack-switching) extension (possibly for compatibility?).
- the [arch/wasm/kernel/syscall.c](https://github.com/tombl/linux/blob/777d95246a8b1dc184e991a76946ccafef392206/arch/wasm/kernel/syscall.c#L19) (and that whole directory) could form the basis for a nice OS teaching course. Implementing the core of an OS on a virtual hypervisor is always [an educational experience](https://anil.recoil.org/projects/unikernels), and this port is based on "real" Linux\!

## Running wasm in Linux kernel mode

On the opposite end of the architecture spectrum, we have a [Linux in-kernel WASM runtime](https://github.com/wasmerio/kernel-wasm). This one allows running userspace code within the kernel space, as motivated by:

> Since WASM is a virtual ISA protected by a virtual machine, we don't need to rely on external hardware and software checks to ensure safety. Running WASM in the kernel avoids most of the overhead introduced by those checks, e.g. system call (context switching) and `copy_{from,to}_user`, therefore improving performance.
> Also, having low-level control means that we can implement a lot of features that were heavy or impossible in userspace, like virtual memory tricks and handling of intensive kernel events (like network packet filtering).
> <cite>\-- [Why run Wasm in the kernel](https://github.com/wasmerio/kernel-wasm?tab=readme-ov-file#why-run-webassembly-in-the-kernel)</cite>

There are some interesting [example applications](https://github.com/wasmerio/wasmer/tree/main/examples#examples) available that they accelerate. They report on the speedup for an echo and http server that can run in kernel space:

> When compiled with the singlepass backend (unoptimized direct x86-64 code generation) and benchmarked using tcpkali/wrk, echo-server is ~10% faster (25210 Mbps / 22820 Mbps) than its native equivalent, and http-server is ~6% faster (53293 Rps / 50083 Rps). Even higher performance is expected when the other two Wasmer backends with optimizations (Cranelift/LLVM) are updated to support generating code for the kernel.
> <cite>\-- [kernel wasm benchmarks](https://github.com/wasmerio/kernel-wasm?tab=readme-ov-file#examples-and-benchmark)</cite>

## Running POSIX applications in the browser

The kernel-wasm port lead me to look more closely at the wasmer runtime, which in turn also extends the [wasi](https://wasi.dev) server-side interface of WASM to support full POSIX compatibility. You can also view this in the [browser as a shell](https://wasmer.sh), where a variety of applications can be compiled to wasm and run as if you had a shell in the browser\!

There is impressive support for POSIX here, as well as an [wasmer/wasix SDK](https://wasmer.io/posts/introducing-the-wasmer-js-sdk) to port existing applications like ffmpeg to run in the browser or [on in a server JS runtime](https://wasmer.io/posts/wasmer-js-sdk-now-supports-node-and-bun).

So what's stopping OCaml --via the [new wasm-of-ocaml compiler](https://tarides.com/blog/2023-11-01-webassembly-support-for-ocaml-introducing-wasm-of-ocaml/) -- from running in the browser? Just the fact that our target runtime depends on the [wasm stack switching](https://github.com/WebAssembly/stack-switching) extension, and [wasmer doesnt yet support that extension](https://github.com/ocaml-wasm/wasm_of_ocaml/issues/101#issuecomment-2464706078). Since there, wasmer 2.3 has [improved stack switching](https://wasmer.io/posts/wasmer-2_3) performance but the extension isn't quite there yet. So if anyone's looking for some experience with language runtime hacking, this might be a good project. I couldn't find any information on whether wasmer is planning on adding support for this extension yet though.

## Running wasm on an FPGA

And last but not least, given all of the above, what would it take to run wasm on an FPGA directly? The existence of the Linux native wasm port is encouraging, since it implies that if you were to get wasm instructions to run directly on an FPGA (just like you might wiht a [MIPS FPGA CPU](https://discuss.ocaml.org/t/hardcaml-mips-cpu-learning-project-and-blog/8088) or a [RISC-V one](https://github.com/ujamjar/hardcaml-riscv)), then you could hook up the rest of the OS ecosystem to this as custom drivers.

I found a few projects around this space that I need to look into more:
- wasmachine is an implementation of the WebAssembly specification in a FPGA. It follows a sequential 6-steps design. <https://github.com/piranna/wasmachine> (see [wasm design discussion](https://github.com/WebAssembly/design/issues/1050))
- a [wasm-fpga-engine](https://github.com/denisvasilik/wasm-fpga-engine) that executes a subset of instructions
- an [FPGA accelerator for WASM instructions](https://www.mdpi.com/2079-9292/13/20/3979). This one came before the stack switching extension though, which might make the implementation in hardware significantly easier.

## And more...

After first posting this, here are incoming updates. [Jonas Kruckenberg](https://bsky.app/profile/jonaskruckenberg.de/post/3lmygmvbidc2i) tells me that he's got an experimental OS called [k23](https://github.com/JonasKruckenberg/k23). This is a microkernel that is built around the idea of using Wasm as the primary execution environment:

> This allows for a number of benefits:
> - Security: WebAssembly is designed to run in a sandboxed environment, making it much harder to exploit.
> - Modularity: WebAssembly modules can depend on each other, importing and exporting functionality and data, forming a modular system where dependency management is a first class citizen.
> - Portability: WebAssembly is designed to be very portable. Forget questions like "is this binary compiled for amd64 or arm?". k23 programs just run wherever.
> - Static Analysis: WebAssembly is famous for being very easy to analyze. This means we can check for bad programs without even running them.
>   <cite>\-- [The k23 manual](https://jonaskruckenberg.github.io/k23/)</cite>
Synopsis: Survey of WebAssembly implementations on non-traditional targets including native Linux port, kernel-mode runtime, POSIX browser support and FPGA ports.
Words: 1130
DOI: 10.59350/ycqj1-b3996

## Related

- [What I learnt at ICFP/SPLASH 2025 about OCaml, Hazel and FP](https://anil.recoil.org/notes/icfp25-what-i-learnt) (note, 2025-10-09)
- [Runtimes à la carte: crossloading native and bytecode OCaml](https://anil.recoil.org/ideas/ocaml-bytecode-native-ffi) (idea, 2025-04-01)
- [Programming FPGAs using OCaml](https://anil.recoil.org/notes/fpgas-hardcaml) (note, 2025-02-07)
- [Unikernels](https://anil.recoil.org/projects/unikernels) (project, 2010-01-01)

---
Canonical: https://anil.recoil.org/notes/wasm-on-exotic-targets
Type: note
License: CC BY 4.0 <https://creativecommons.org/licenses/by/4.0/>
Tags: wasm, systems, fpga, ocaml
