Linux内核的WebAssembly (WASM) 架构支持
WebAssembly (WASM) arch support for the Linux kernel

原始链接: https://github.com/joelseverin/linux-wasm

该项目旨在创建一个完全可运行的 Linux 系统,该系统可以在 Web 浏览器中执行,并使用原生 WebAssembly (Wasm)。它通过将 Linux 内核 (6.4.16)、musl libc (1.2.5) 和 BusyBox (1.36.1) 编译为 Wasm 来实现,同时使用修补后的 LLVM 工具链 (18.1.2) 实现 Wasm 链接。 该脚本支持在主机上或在 Docker 容器中构建和运行该系统(提供了基础构建环境和隔离的构建过程)。关键修改包括用于 Wasm 架构支持和 Wasm 控制台的内核补丁,以及允许 musl 和 BusyBox 与 Wasm 工具链编译的修改。 创建了一个最小的 initramfs 来启动系统进入 shell。一个基本的 JavaScript 运行时演示了如何托管 Wasm Linux 环境。请注意,由于 Wasm 的限制,Linux 系统以 NOMMU 配置构建。该项目包含一个 `linux-wasm.sh` 脚本,用于管理下载、构建和使用。

## 浏览器中的 Linux 与 WebAssembly 一个新项目允许使用 WebAssembly (WASM) 直接在网络浏览器中运行完整的 Linux 发行版,实现接近原生速度。这是通过将整个系统编译为 WASM 来实现的,每个进程作为一个 Web Worker 运行。 初步测试表明,与以前的模拟方法相比,性能有了显著提升——一项基准测试实现了 170 倍更快的成果。虽然目前仍存在一些错误,但该项目展示了轻量级 WASM 基础操作系统运行时在云终端和增强型科学计算环境(Jupyter notebooks)等应用中的潜力。 仍然存在挑战,包括 Firefox 中的调试以及潜在的网络限制。然而,这种方法绕过了传统的模拟,提供了一种潜在更快、更有效的方式,可以在网络浏览器中直接运行 Linux 应用程序。 诸如 container2wasm 和 WebCM 之类的相关项目提供了替代方法,而这种新的实现侧重于消除 ISA 转换层以提高速度。
相关文章

原文

This project contains scripts to download, build and run a Linux system that can executed on the web, using native WebAssembly (Wasm).

These scripts can be run in the following way:

  • Directly on a host machine.
  • In a generic docker container.
  • In a specific docker container (see Dockerfile).

The project is built and assembled from following pieces of software:

  • LLVM Project:
    • Base version: 18.1.2
    • Patches:
      • A hack patch that enables GNU ld-style linker scripts in wasm-ld.
    • Artifacts: clang, wasm-ld (from lld), compiler-rt
  • Linux kernel:
    • Base version: 6.4.16
    • Patches:
      • A patch for adding Wasm architecture support to the kernel.
      • A wasm binfmt feature patch, enabling .wasm files to run as executables.
      • A console driver for a Wasm "web console".
    • Artifacts: vmlinux, exported (unmodified) kernel headers
    • Dependencies: clang, wasm-ld with linker script support, (compiler-rt is not needed)
  • musl:
    • Base version: 1.2.5
    • Patches:
      • A hack patch (minimal and incorrect) that:
        • Adds Wasm as a target to musl (I guessed and cheated a lot on this one).
        • Allows musl to be built using clang and wasm-ld (linker script support may be needed).
    • Atifacts: musl libc
    • Dependencies: clang, wasm-ld, compiler-rt
  • Linux kernel headers for BusyBox
    • Base version: from the kernel
    • Patches:
      • A series of patches, originally hosted by Sabotage Linux, but modified to suit a newer kernel. These patches allow BusyBox to include kernel headers (which is not really supported by Linux). This magically just "works" with glibc but needs modding for musl.
    • Artifacts: modified kernel headers
    • Dependencies: exported Linux kernel headers
  • BusyBox:
    • Base version: 1.36.1
    • Patches:
      • A hack patch (minimal and incomplete) that:
        • Allows BuxyBox to be built using clang and wasm-ld (linker script support might be unnecessary).
        • Adds a Wasm defconfig.
    • Artifacts: BusyBox installation (base binary and symlinks for ls, cat, mv etc.)
    • Dependencies: musl libc, modified headers for BusyBox
  • A minimal initramfs:
    • Notes:
      • Packages up the busybox installation into a compessed cpio archive.
      • It sets up a pty for you (for proper signal/session/job management) and drops you into a shell.
    • Artifacts: initramfs.cpio.gz
    • Dependencies: BusyBox installation
  • A runtime:
    • Notes:
      • Some example code of how a minimal JavaScript Wasm host could look like.
      • Error handling is not very graceful, more geared towards debugging than user experience.
      • This is the glue code that kicks everything off, spawns web workers, creates Wasm instances etc.

Hint: Wasm lacks an MMU, meaning that Linux needs to be built in a NOMMU configuration. Wasm programs thus need to be built using -fPIC/-shared. Alternatively, existing Wasm programs can run together with a proxy that does syscalls towards the kernel. In such a case, each thread that wishes to independently execute syscalls should map to a thread in the proxy. The drawback of such an approach is that memory cannot be mapped and shared between processes. However, from a memory protection standpoint, this property could also be beneficial.

Run ./linux-wasm.sh to see usage. Downloads happen first, building afterwards. You may partially select what to download or (re)-build.

Due to a bug in LLVM's build system, building LLVM a second time fails when building runtimes (complaining that clang fails to build a simple test program). A workaround is to build it yet again (it works each other time, i.e. the 1st, 3rd, 5th etc. time).

Due to limitations in the Linux kernel's build system, the absolute path of the cross compiler (install path of LLVM) cannot contain spaces. Since LLVM is built by linux-wasm.sh, it more or less means its workspace directory (or at least install directory) has to be in a space free path.

The following commands should be executed in this repo root.

There are two containers:

  • linux-wasm-base: Contains an Ubuntu 20.04 environment with all tools installed for building (e.g. cmake, gcc etc.).
  • linux-wasm-contained: Actually builds everything into the container. Meant as a dispoable way to build everything isolated.

Create the containers:

docker build -t linux-wasm-base:dev ./docker/linux-wasm-base
docker build -t linux-wasm-contained:dev ./docker/linux-wasm-contained

Note that the latter command will copy linux-wasm.sh, in its current state, into the container.

To launch a simple docker container with a mapping to host (recommended for development):

docker run -it --name my-linux-wasm --mount type=bind,src="$(pwd)",target=/linux-wasm linux-wasm-base:dev bash
(Inside the bash prompt, run for example:) /linux-wasm/linux-wasm.sh all

To actually build everything inside the container (mostly useful for build servers):

docker run -it -name full-linux-wasm linux-wasm-contained:dev /linux-wasm/linux-wasm.sh all

To change workspace folder, docker run -e LW_WORKSPACE=/path/to/workspace ...blah... can be used. This may be useful together with docker volumes.

联系我们 contact @ memedata.com