Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
saza-ku committed Dec 29, 2023
0 parents commit 66e1d13
Show file tree
Hide file tree
Showing 57 changed files with 5,930 additions and 0 deletions.
36 changes: 36 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
FROM mcr.microsoft.com/devcontainers/rust:1-1-bookworm

RUN apt-get update && apt-get install -y cmake

ARG LLVM_URL=https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.0/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4.tar.xz
ARG ZIG_VERSION=zig-linux-x86_64-0.12.0-dev.1856+94c63f31f

ENV PATH="/usr/bin/zig:${PATH}"
ENV PATH=/usr/local/llvm/bin:$PATH
ENV LLVM_SYS_150_PREFIX=/usr/local/llvm/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4

# install llvm
RUN mkdir -p /usr/local/llvm \
&& wget ${LLVM_URL} -O /tmp/llvm.tar.xz \
&& tar -xvf /tmp/llvm.tar.xz -C /usr/local/llvm \
&& rm /tmp/llvm.tar.xz

WORKDIR /work

RUN git clone https://github.com/Mewz-project/Wasker.git \
&& cd Wasker \
&& cargo build --release \
&& cp target/release/wasker /usr/bin

RUN apt-get update && \
apt-get install -y \
curl \
xz-utils \
qemu-system \
qemu-system-common \
qemu-utils \
cmake

RUN curl -SL https://ziglang.org/builds/${ZIG_VERSION}.tar.xz \
| tar -xJC /tmp \
&& mv /tmp/${ZIG_VERSION} /usr/bin/zig
7 changes: 7 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "Mewz Dev Container",
"build": {
"context": "..",
"dockerfile": "./Dockerfile"
},
}
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.github
.gitignore
.gitmodules
build
zig-out
zig-cache
.gdbinit
disk.o
disk.tar
README.md
2 changes: 2 additions & 0 deletions .gdbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target remote localhost:12345
file zig-out/bin/mewz.elf
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
iso_root/
zig-out/
zig-cache/
build/
virtio-net.pcap
disk.tar
disk.o
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "submodules/lwip"]
path = submodules/lwip
url = https://git.savannah.nongnu.org/git/lwip.git
[submodule "submodules/newlib"]
path = submodules/newlib
url = https://sourceware.org/git/newlib-cygwin.git
22 changes: 22 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM ghcr.io/mewz-project/wasker:latest

ARG ZIG_VERSION=zig-linux-x86_64-0.12.0-dev.1856+94c63f31f

ENV PATH="/usr/bin/zig:${PATH}"

WORKDIR /mewz

RUN apt-get update && \
apt-get install -y curl xz-utils qemu-system qemu-system-common qemu-utils git cmake libstdc++6 build-essential && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

RUN curl -SL https://ziglang.org/builds/${ZIG_VERSION}.tar.xz \
| tar -xJC /tmp \
&& mv /tmp/${ZIG_VERSION} /usr/bin/zig

COPY . .

RUN ./scripts/build-newlib.sh && ./scripts/build-lwip.sh

ENTRYPOINT [ "./scripts/run.sh" ]
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Mewz

![](img/mewz-logo.png)

Mewz is a unikernel designed specifically for running Wasm applications and compatible with WASI.

## What's new with Mewz

There are now various Wasm runtimes, but they operate on general-purpose operating systems such as Linux or Windows.

Mewz is **a specialized kernel designed for running Wasm**. Mewz runs a single Wasm application within the kernel by linking it together during the build process with the Wasm application. (A kernel configured in this manner is commonly referred to as a **unikernel**.) In this way, Mewz provides **the minimal required features and environment for executing Wasm**.

![](img/mewz-architecture.png)

## Quick Start

### Option1: Docker

We prepare for a Docker image that has a environment for running Mewz.

```sh
curl -o helloworld.wat https://raw.githubusercontent.com/Mewz-project/Wasker/main/helloworld.wat
docker run -v .:/volume ghcr.io/mewz-project/mewz helloworld.wat
```

This image internally run [Wasker](https://github.com/mewz-project/wasker), build Mewz, and run it on QEMU.

![](img/mewz-demo.gif)

### Option2: Dev Container

You can use Dev Container on GitHub Codespaces or your local VSCode.

To start Codespaces,

- Click Code -> Codespaces -> New codespace on this repository page.
- Wait for a while, then you can see VSCode on browser.
- Open terminal on VSCode

```sh
# On the Dev Container
git submodule update --init
curl -o helloworld.wat https://raw.githubusercontent.com/Mewz-project/Wasker/main/helloworld.wat
wasker helloworld.wat
zig build -Dapp-obj=wasm.o run
```

### Option3: Build from source

Compile a Wasm file into a native object file, using [Wasker](https://github.com/mewz-project/wasker). Follow the instruction [here](https://github.com/mewz-project/wasker#how-to-run-wasker).

Then, build Mewz and run it on QEMU with the following commands.

```sh
zig build -Dapp-obj=<path to the object file generated by Wasker> run
```

To use file systems, specify the directory by `-Ddir=<path to dir>`.

> [!WARNING]
> This option makes an archive of the directory by `tar` and attach it to QEMU.
> [!NOTE]
> QEMU's port 1234 is mapped to localhost:1234.
### Current Status


| Feature | Status |
|:---------------------:| :--------------------------------------------------------------------------------------------------: |
| WASI Preview 1 | In Progress: Partial Implementation (Please refer to https://github.com/Mewz-project/Mewz/issues/1) |
| Socket | ✅ (WasmEdge Compatible) |
| Component Model | Not yet |
| File System | On memory, read only |
| Network ||
113 changes: 113 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
const std = @import("std");
const Build = @import("std").Build;
const Target = @import("std").Target;
const CrossTarget = @import("std").zig.CrossTarget;
const Feature = @import("std").Target.Cpu.Feature;

pub fn build(b: *Build) !void {
const kernel_options = b.addOptions();

const obj_path_option = b.option([]const u8, "app-obj", "object file of application");
if (obj_path_option) |_| {
kernel_options.addOption(bool, "has_wasm", true);
} else {
kernel_options.addOption(bool, "has_wasm", false);
}

const test_option = b.option(bool, "test", "run tests");
if (test_option) |t| {
kernel_options.addOption(bool, "is_test", t);
} else {
kernel_options.addOption(bool, "is_test", false);
}

const log_level_option = b.option([]const u8, "log-level", "log level");
if (log_level_option) |l| {
kernel_options.addOption([]const u8, "log_level", l);
} else {
kernel_options.addOption([]const u8, "log_level", "fatal");
}

const fs_path_option = b.option([]const u8, "fs-path", "path to filesystem");
if (fs_path_option) |p| {
std.debug.print("building fs: {s}\n", .{p});
kernel_options.addOption(bool, "has_fs", true);
} else {
kernel_options.addOption(bool, "has_fs", false);
}

const features = Target.x86.Feature;

var disabled_features = Feature.Set.empty;
var enabled_features = Feature.Set.empty;

disabled_features.addFeature(@intFromEnum(features.mmx));
disabled_features.addFeature(@intFromEnum(features.sse));
disabled_features.addFeature(@intFromEnum(features.sse2));
disabled_features.addFeature(@intFromEnum(features.avx));
disabled_features.addFeature(@intFromEnum(features.avx2));
enabled_features.addFeature(@intFromEnum(features.soft_float));

const target = CrossTarget{ .cpu_arch = Target.Cpu.Arch.x86_64, .os_tag = Target.Os.Tag.freestanding, .cpu_features_sub = disabled_features, .cpu_features_add = enabled_features };

const optimize = b.standardOptimizeOption(.{});

const newlib_build_cmd = b.addSystemCommand(&[_][]const u8{"./scripts/build-newlib.sh"});
const lwip_build_cmd = b.addSystemCommand(&[_][]const u8{"./scripts/build-lwip.sh"});

const kernel = b.addExecutable(.{
.name = "mewz.elf",
.root_source_file = .{ .path = "src/main.zig" },
.optimize = optimize,
.target = target,
.linkage = std.build.CompileStep.Linkage.static,
});
kernel.code_model = .kernel;
kernel.setLinkerScriptPath(.{ .path = "src/x64.ld" });
kernel.addAssemblyFile(Build.LazyPath{ .path = "src/boot.S" });
kernel.addAssemblyFile(Build.LazyPath{ .path = "src/interrupt.S" });
kernel.addObjectFile(Build.LazyPath{ .path = "build/newlib/libc.a" });
kernel.addObjectFile(Build.LazyPath{ .path = "build/lwip/libtcpip.a" });
kernel.addObjectFile(Build.LazyPath{ .path = "build/lwip/liblwipcore.a" });
kernel.addObjectFile(Build.LazyPath{ .path = "build/lwip/liblwipallapps.a" });
kernel.addCSourceFile(Build.Step.Compile.CSourceFile{ .file = Build.LazyPath{ .path = "src/c/newlib_support.c" }, .flags = &[_][]const u8{ "-I", "submodules/newlib/newlib/libc/include" } });
kernel.addCSourceFile(Build.Step.Compile.CSourceFile{ .file = Build.LazyPath{ .path = "src/c/lwip_support.c" }, .flags = &[_][]const u8{ "-I", "submodules/newlib/newlib/libc/include" } });
if (obj_path_option) |p| {
kernel.addObjectFile(Build.LazyPath{ .path = p });
}
if (fs_path_option) |_| {
kernel.addObjectFile(Build.LazyPath{ .path = "disk.o" });
}
kernel.addOptions("options", kernel_options);
b.installArtifact(kernel);

const kernel_step = b.step("kernel", "Build the kernel");
kernel.step.dependOn(&newlib_build_cmd.step);
kernel.step.dependOn(&lwip_build_cmd.step);
if (fs_path_option) |p| {
const fs_build_cmd = b.addSystemCommand(&[_][]const u8{ "./scripts/build-fs.sh", p });
kernel.step.dependOn(&fs_build_cmd.step);
}
kernel_step.dependOn(&kernel.step);

const rewrite_kernel_cmd = b.addSystemCommand(&[_][]const u8{"./scripts/rewrite-kernel.sh"});
rewrite_kernel_cmd.step.dependOn(b.getInstallStep());

const run_cmd_str = [_][]const u8{"./scripts/run-qemu.sh"};

const run_cmd = b.addSystemCommand(&run_cmd_str);
run_cmd.step.dependOn(&rewrite_kernel_cmd.step);

const run_step = b.step("run", "Run the kernel");
run_step.dependOn(&run_cmd.step);

const debug_cmd_str = run_cmd_str ++ [_][]const u8{
"--debug",
};

const debug_cmd = b.addSystemCommand(&debug_cmd_str);
debug_cmd.step.dependOn(&rewrite_kernel_cmd.step);

const debug_step = b.step("debug", "Debug the kernel");
debug_step.dependOn(&debug_cmd.step);
}
Binary file added img/mewz-architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/mewz-demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/mewz-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions lwip-wrapper/.vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/../submodules/lwip/src/include"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "linux-clang-x64"
}
],
"version": 4
}
9 changes: 9 additions & 0 deletions lwip-wrapper/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"files.associations": {
"timeouts.h": "c",
"init.h": "c",
"opt.h": "c",
"debug.h": "c",
"arch.h": "c"
}
}
20 changes: 20 additions & 0 deletions lwip-wrapper/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
set(LWIP_DIR
${CMAKE_CURRENT_SOURCE_DIR}/../submodules/lwip
)

set(LWIP_INCLUDE_DIRS
${LWIP_DIR}/src/include
${CMAKE_CURRENT_SOURCE_DIR}
)

set (LWIP_DEFINITIONS LWIP_DEBUG=1)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_BUILD_TYPE Debug)

set(LWIP_COMPILER_FLAGS -ffreestanding -fno-stack-protector)
include(${LWIP_DIR}/src/Filelists.cmake)

add_library(tcpip STATIC tcpip.c)
target_include_directories(tcpip PRIVATE ${LWIP_INCLUDE_DIRS})
target_compile_options(tcpip PRIVATE -ffreestanding -fno-stack-protector)
target_link_libraries(tcpip lwipallapps lwipcore)
Empty file added lwip-wrapper/arch/cc.h
Empty file.
Loading

0 comments on commit 66e1d13

Please sign in to comment.