include + update old linux targets/host.c

This commit is contained in:
2026-03-05 19:16:03 +01:00
parent 6ab17c98e9
commit e6237cc06e
10 changed files with 241 additions and 125 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
examples/build-*/
/examples/bochslog.txt
/bochslog.txt

View File

@ -7,8 +7,5 @@ run:
run-external:
docker run --rm -it -v "./examples:/home/ubuntu/examples" gitea.vps.chriphost.de/christoph/wasm-base:latest /usr/bin/fish
bochs:
bochs -f ./examples/arch/bochs/bochsrc-docker.txt -q
bochs-host:
nix shell nixpkgs#bochs --command sh -c "bochs -f ./examples/arch/bochs/bochsrc-host.txt -q"
nix shell nixpkgs#bochs --command sh -c "bochs -q -f ./examples/arch/bochs/bochsrc-host.txt -q"

View File

@ -16,17 +16,25 @@ WASI_CFLAGS := \
# WASM -> Baremetal
WAMR := /opt/wamr
IWASM_LIB := /opt/wamr-libiwasm
CC := /opt/crosscompiler/bin/i686-elf-gcc
# NOTE: When compiling I get "error: bp cannot be used in asm here"
# I could remove "ebp" from the clobber list (ARCH_ASM_CLOBBER_ALL) or
WAMRC := /opt/wamr-wamrc/wamrc
WAMRCFLAGS := \
--target=i386 \
--cpu=generic
XXD := busybox xxd
# NOTE: make build-sum: "error: bp cannot be used in asm here"
# could remove "ebp" from the clobber list (ARCH_ASM_CLOBBER_ALL) or
# use the -fomit-frame-pointer flag to tell gcc it shouldn't rely on ebp for enter/leave...
CC := /opt/crosscompiler/bin/i686-elf-gcc
CFLAGS := \
-I. \
-O0 \
-m32 \
-ffunction-sections \
-fomit-frame-pointer
-fomit-frame-pointer \
-ggdb
IWASM_LIB := /opt/wamr-libiwasm # Baremetal
LDFLAGS = \
-Wl,-T linker.ld \
$^ \
@ -44,8 +52,26 @@ INCL := \
-I${WAMR}/core/shared/utils \
-I${WAMR}/core/shared/platform/baremetal \
-I/opt/crosscompiler/i686-elf/include
WAMRC := /opt/wamr-wamrc/wamrc
XXD := busybox xxd
CC_LINUX := gcc
CFLAGS_LINUX := \
-I. \
-O0 \
-m32 \
-ffunction-sections \
-ggdb
IWASM_LIB_LINUX := /opt/wamr-libiwasm-linux
LDFLAGS_LINUX = \
$^ \
-m32 \
-Wl,-rpath,${IWASM_LIB_LINUX} \
-L${IWASM_LIB_LINUX} \
-liwasm \
-lm
INCL_LINUX := \
-I${WAMR}/core/iwasm/include \
-I${WAMR}/core/shared/utils \
-I${WAMR}/core/shared/platform/linux
################################################################
# C -> WASM
@ -65,9 +91,9 @@ ${BUILD_DIR}/%/module.wasm: %.c
# ${CC} ${LDFLAGS} -o $@
################################################################
# WASM -> AOT -> Loaded by Runtime
# WASM -> AOT -> Loaded by Runtime (FAIL)
${BUILD_DIR}/%/module.aot: ${BUILD_DIR}/%/module.wasm
${WAMRC} -o $@ $<
${WAMRC} ${WAMRCFLAGS} -o $@ $<
${BUILD_DIR}/%/module_wasm.c: ${BUILD_DIR}/%/module.aot
${XXD} -i $< > $@
@ -90,6 +116,20 @@ ${BUILD_DIR}/syscalls.o: syscalls.c
${BUILD_DIR}/%/system.elf: ${BUILD_DIR}/%/system.o ${BUILD_DIR}/syscalls.o ${BUILD_DIR}/startup.o
${CC} ${LDFLAGS} -o $@
################################################################
# WASM -> AOT -> Loaded by Runtime (Host/Linux)
${BUILD_DIR}/%/system-linux.o: ${BUILD_DIR}/%/module_wasm.c
cp embed/host-linux.c ${BUILD_DIR}/$*/module_host-linux.c
sed -i \
-e "s/__WASM_ARRAY_FILE__/module_wasm.c/g" \
-e "s/__WASM_ARRAY__/build_bochs_$*_module_aot/g" \
-e "s/__WASM_ARRAY_LEN__/build_bochs_$*_module_aot_len/g" \
${BUILD_DIR}/$*/module_host-linux.c
${CC_LINUX} ${CFLAGS_LINUX} ${INCL_LINUX} -c ${BUILD_DIR}/$*/module_host-linux.c -o $@
${BUILD_DIR}/%/system-linux.elf: ${BUILD_DIR}/%/system-linux.o
${CC_LINUX} ${LDFLAGS_LINUX} -o $@
################################################################
# Bochs
${BUILD_DIR}/%/system.iso: ${BUILD_DIR}/%/system.elf
@ -167,6 +207,17 @@ build-$1: ${BUILD_DIR}/$1/system.iso
trace-$1: ${BUILD_DIR}/$1/trace.pb
objdump-$1:
objdump --disassemble --disassembler-options intel --disassembler-color=on --source ${BUILD_DIR}/$1/system.elf
objdump --disassemble --disassembler-options intel --disassembler-color=off --source ${BUILD_DIR}/$1/system.elf | less
linux-build-$1: ${BUILD_DIR}/$1/system-linux.elf
linux-run-$1: ${BUILD_DIR}/$1/system-linux.elf
${BUILD_DIR}/$1/system-linux.elf
linux-gdb-$1: ${BUILD_DIR}/$1/system-linux.elf
gdb --tui ${BUILD_DIR}/$1/system-linux.elf
bochs-run-$1: ${BUILD_DIR}/$1/system.iso
bochs -q -f arch/bochs/bochsrc-docker.txt
endef

View File

@ -4,7 +4,6 @@ romimage: file="/home/christoph/Notes/TU/MastersThesis/3 Wasm/examples/arch/boch
vgaromimage: file="/home/christoph/Notes/TU/MastersThesis/3 Wasm/examples/arch/bochs/vgabios.bin"
ata0-master: type=cdrom, path="/home/christoph/Notes/TU/MastersThesis/3 Wasm/examples/build-bochs/sum/system.iso", status=inserted
boot: cdrom
log: bochslog.txt
clock: sync=realtime, time0=local
cpu: count=1, ips=1000000
sound: driver=dummy

View File

@ -13,20 +13,41 @@
# checksum: -(magic+flags)
.long -(0x1BADB002 + 0x3)
# the initial kernel stack
.section .kernel_stack
.global os_stack
.size os_stack, 4096
# NOTE: New Start
# .section .gdt
# gdt_start:
# .quad 0x0000000000000000 # null descriptor
# .quad 0x00cf9a000000ffff # code segment descriptor: base=0, limit=4GB, 32-bit code
# .quad 0x00cf92000000ffff # data segment descriptor: base=0, limit=4GB, 32-bit data
# gdt_end:
#
# gdt_descriptor:
# .word gdt_end - gdt_start - 1 # limit
# .long gdt_start # base
#
# .section .idt
# idt_table:
# .space 256*8 # 256 entries x 8 bytes each
# idt_descriptor:
# .word 256*8-1 # limit
# .long idt_table # base
# NOTE: New End
#.Lstack_bottom:
os_stack:
.byte 0
#.skip 16384 # 16 KiB
.skip 4094 # 4 KiB
.byte 0
.Lstack_top:
.byte 0
.skip 65565 # 64 KiB
# .skip 16384 # 16 KiB
# .skip 4094 # 4 KiB
.byte 0
.Lstack_top:
# The linker script specifies _start as the entry point to the kernel and the
@ -36,7 +57,9 @@ os_stack:
.global _start
.type _start, @function
_start:
# Welcome to kernel mode!
# NOTE: Old Start
# Welcome to kernel mode!
# To set up a stack, we simply set the esp register to point to the top of
# our stack (as it grows downwards).
movl $.Lstack_top, %esp
@ -54,6 +77,34 @@ _start:
.Lhang:
jmp .Lhang
# NOTE: Old End
# NOTE: New Start
# cli
#
# lgdt gdt_descriptor # GDT
# lidt idt_descriptor # IDT Stub
#
# # set up segment registers (flat 32-bit)
# movw $0x10, %ax
# movw %ax, %ds
# movw %ax, %es
# movw %ax, %fs
# movw %ax, %gs
# movw %ax, %ss
# movl $.Lstack_top, %esp # set stack
#
# # call main C function
# call os_main
#
# cli
# hlt
# .Lhang:
# jmp .Lhang
# NOTE: New End
# Set the size of the _start symbol to the current location '.' minus its start.
# This is useful when debugging or when you implement call tracing.
.size _start, . - _start

View File

@ -1,84 +0,0 @@
# C -> WASM
WASI_ROOT := /opt/wasi-sdk
WASI_CC := ${WASI_ROOT}/bin/clang
WASI_CFLAGS := --target=wasm64 \
--sysroot=${WASI_ROOT}/share/wasi-sysroot \
-z stack-size=4096 \
-O0 -g -nostdlib \
-Wl,--no-entry \
-Wl,--initial-memory=65536 \
-Wl,--export-all \
-Wl,--export=__heap_base \
-Wl,--export=__data_end
# WASM -> Baremetal
WAMR := /opt/wamr
IWASM_LIB := /opt/wamr-libiwasm-64
CC := gcc
# NOTE: When compiling I get "error: bp cannot be used in asm here"
# I could remove "ebp" from the clobber list (ARCH_ASM_CLOBBER_ALL) or
# use the -fomit-frame-pointer flag to tell gcc it shouldn't rely on ebp for enter/leave...
CFLAGS := -I. -O0 -g -ffunction-sections -std=c11 -fomit-frame-pointer
LDFLAGS = $^ -Wl,--build-id=none -static -nostdlib \
-Wl,-rpath,${IWASM_LIB} -L${IWASM_LIB} -liwasm -lgcc
INCL := -I${WAMR}/core/iwasm/include \
-I${WAMR}/core/shared/utils \
-I${WAMR}/core/shared/platform/baremetal
WAMRC := /opt/wamr-wamrc/wamrc
WAMRCFLAGS := --target=i386 --format=object
XXD := busybox xxd
################################################################
# C -> WASM
${BUILD_DIR}/%/module.wasm: %.c
mkdir -p $(shell dirname $@)
${WASI_CC} ${WASI_CFLAGS} $< -o $@
################################################################
# WASM -> Native Object File
# ${BUILD_DIR}/%/system.o: ${BUILD_DIR}/%/module.wasm
# ${WAMRC} ${WAMRCFLAGS} -o ${BUILD_DIR}/$*/system.o ${BUILD_DIR}/$*/module.wasm
#
# ${BUILD_DIR}/startup.o: arch/bochs/startup.s
# ${CC} $< ${CFLAGS} -c -o $@
#
# ${BUILD_DIR}/%/system.elf: ${BUILD_DIR}/%/system.o ${BUILD_DIR}/startup.o
# ${CC} ${LDFLAGS} -o $@
################################################################
# WASM -> AOT -> Loaded by Runtime
${BUILD_DIR}/%/module.aot: ${BUILD_DIR}/%/module.wasm
${WAMRC} -o $@ $<
${BUILD_DIR}/%/module_wasm.c: ${BUILD_DIR}/%/module.aot
${XXD} -i $< > $@
${BUILD_DIR}/%/system.o: ${BUILD_DIR}/%/module_wasm.c
cp embed/host.c ${BUILD_DIR}/$*/module_host.c
sed -i \
-e "s/__WASM_ARRAY_FILE__/module_wasm.c/g" \
-e "s/__WASM_ARRAY__/build_linux_$*_module_aot/g" \
-e "s/__WASM_ARRAY_LEN__/build_linux_$*_module_aot_len/g" \
${BUILD_DIR}/$*/module_host.c
${CC} ${CFLAGS} ${INCL} -c ${BUILD_DIR}/$*/module_host.c -o $@
${BUILD_DIR}/startup.o: arch/bochs/startup.s
${CC} $< ${CFLAGS} -c -o $@
${BUILD_DIR}/%/system.elf: ${BUILD_DIR}/%/system.o ${BUILD_DIR}/startup.o
${CC} ${LDFLAGS} -o $@
define arch-make-targets
build-$1: ${BUILD_DIR}/$1/system.elf
gdb-$1:
gdb --tui ${BUILD_DIR}/$1/system.elf
valgrind-$1:
valgrind ${BUILD_DIR}/$1/system.elf
objdump-$1:
objdump --disassemble --start-address=0x401000 --stop-address=0x401200 --disassembler-options intel --disassembler-color=on --source ${BUILD_DIR}/$1/system.elf
endef

View File

@ -0,0 +1,89 @@
// https://github.com/bytecodealliance/wasm-micro-runtime/blob/WAMR-2.4.4/doc/embed_wamr.md
#include "lib.c"
#include "bh_platform.h"
#include "wasm_export.h"
#include "__WASM_ARRAY_FILE__"
#include <stdio.h>
#define STACK_SIZE (4 * 1024)
#define HEAP_SIZE STACK_SIZE
#define RUNTIME_POOL_SIZE 4 * STACK_SIZE
// TODO: Set this up so the lsp actually finds the includes...
// MAIN() {
int main(int argc, char *argv[]) {
char error_buf[128];
wasm_module_t module;
wasm_module_inst_t module_inst;
wasm_function_inst_t func;
wasm_exec_env_t exec_env;
/* initialize the wasm runtime */
static char global_heap_buf[RUNTIME_POOL_SIZE];
static RuntimeInitArgs init_args;
memset(&init_args, 0, sizeof(RuntimeInitArgs));
// init_args.mem_alloc_type = Alloc_With_System_Allocator;
init_args.mem_alloc_type = Alloc_With_Pool;
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
init_args.max_thread_num = 1;
if (!wasm_runtime_full_init(&init_args)) {
return 1;
}
/* parse the WASM file from buffer and create a WASM module */
module = wasm_runtime_load(__WASM_ARRAY__, __WASM_ARRAY_LEN__, error_buf,
sizeof(error_buf));
if (!module) {
printf("Load failed: %s\n", error_buf);
return 1;
}
/* create an instance of the WASM module (WASM linear memory is ready) */
module_inst = wasm_runtime_instantiate(module, STACK_SIZE, HEAP_SIZE,
error_buf, sizeof(error_buf));
if (!module_inst) {
printf("Inst failed: %s\n", error_buf);
return 1;
}
/* lookup a WASM function by its name, the function signature can NULL here */
func = wasm_runtime_lookup_function(module_inst, "wasm_module");
/* create an execution environment to execute arbitrary WASM functions */
exec_env = wasm_runtime_create_exec_env(module_inst, STACK_SIZE);
/* arguments are always transferred in 32-bit element */
uint32 args[1];
/* call an arbitrary WASM function */
// MARKER(start_trace);
if (!wasm_runtime_call_wasm(exec_env, func, 0, args)) {
/* function wasn't called correctly */
printf("Failed to call function 'wasm_module'!\n");
}
// MARKER(stop_trace);
printf("Sum: %d\n", args[0]);
/* the return value is stored in args[0] */
if (args[0] == 100) {
// MARKER(ok_marker);
} else {
// MARKER(fail_marker);
}
wasm_runtime_destroy_exec_env(exec_env);
wasm_runtime_deinstantiate(module_inst);
wasm_runtime_unload(module);
wasm_runtime_destroy();
return 0;
}

View File

@ -8,7 +8,8 @@
#include "__WASM_ARRAY_FILE__"
#define STACK_SIZE (4 * 1024)
#define HEAP_SIZE (4 * 1024)
#define HEAP_SIZE STACK_SIZE
#define RUNTIME_POOL_SIZE 4 * STACK_SIZE
// TODO: Set this up so the lsp actually finds the includes...
@ -20,10 +21,11 @@ MAIN() {
wasm_exec_env_t exec_env;
/* initialize the wasm runtime */
static char global_heap_buf[HEAP_SIZE];
RuntimeInitArgs init_args;
static char global_heap_buf[RUNTIME_POOL_SIZE];
static RuntimeInitArgs init_args;
memset(&init_args, 0, sizeof(RuntimeInitArgs));
// init_args.mem_alloc_type = Alloc_With_System_Allocator;
init_args.mem_alloc_type = Alloc_With_Pool;
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
@ -36,10 +38,20 @@ MAIN() {
module = wasm_runtime_load(__WASM_ARRAY__, __WASM_ARRAY_LEN__, error_buf,
sizeof(error_buf));
if (!module) {
// printf("Load failed: %s\n", error_buf);
return;
}
/* create an instance of the WASM module (WASM linear memory is ready) */
module_inst = wasm_runtime_instantiate(module, STACK_SIZE, HEAP_SIZE,
error_buf, sizeof(error_buf));
if (!module_inst) {
// printf("Inst failed: %s\n", error_buf);
return;
}
/* lookup a WASM function by its name, the function signature can NULL here */
func = wasm_runtime_lookup_function(module_inst, "wasm_module");
@ -53,11 +65,11 @@ MAIN() {
MARKER(start_trace);
if (!wasm_runtime_call_wasm(exec_env, func, 0, args)) {
/* function wasn't called correctly */
POSIX_PRINTF("Failed to call function 'wasm_module'!\n");
// printf("Failed to call function 'wasm_module'!\n");
}
MARKER(stop_trace);
POSIX_PRINTF("Sum: %d\n!", args[0]);
// printf("Sum: %d\n", args[0]);
/* the return value is stored in args[0] */
if (args[0] == 100) {
@ -70,4 +82,6 @@ MAIN() {
wasm_runtime_deinstantiate(module_inst);
wasm_runtime_unload(module);
wasm_runtime_destroy();
return;
}

View File

@ -18,7 +18,7 @@ SECTIONS {
/* Code and readonly data */
.text : {
/* fill gaps with int3 opcode to detect invalid jumps */
/* TODO: This crashes bochs */
/* TODO: Crashes */
FILL(0xcc)
/* multiboot header */

View File

@ -47,8 +47,7 @@ RUN mkdir gcc-build && cd gcc-build \
# && PATH="$CROSSPREFIX/bin:$PATH" make all-target-libstdc++-v3 -j$(nproc) \
# && PATH="$CROSSPREFIX/bin:$PATH" make install-target-libstdc++-v3
# Build newlib - it seems like because I use the same gcc prefix
# I don't even need to specify it as an include when building?
# Build newlib in the gcc prefix - don't need to specify include paths
ARG NEWLIBVERSION=4.1.0
WORKDIR /
RUN wget ftp://sourceware.org/pub/newlib/newlib-$NEWLIBVERSION.tar.gz \
@ -85,10 +84,6 @@ RUN apt-get update \
wget \
&& apt-get clean
# TODO: Can't find pthread on X86_32
# RUN ln -s /usr/lib/x86_64-linux-gnu/libpthread.so.0 /usr/lib/x86_64-linux-gnu/libpthread.so
# RUN ln -s /usr/lib32/libpthread.so.0 /usr/lib32/libpthread.so
RUN python3 -m pip config set global.break-system-packages true
# Clone WAMR
@ -185,12 +180,13 @@ RUN mkdir build_libiwasm && cd build_libiwasm \
.. \
&& make -j$(nproc)
# Build WAMR libiwasm for the host system
WORKDIR /wamrlib
RUN mkdir build_libiwasm_64 && cd build_libiwasm_64 \
RUN mkdir build_libiwasm_linux && cd build_libiwasm_linux \
&& cmake \
-DWAMR_BUILD_PLATFORM=baremetal \
-DWAMR_BUILD_TARGET=X86_64 \
-DWAMR_BUILD_AOT=0 \
-DWAMR_BUILD_PLATFORM=linux \
-DWAMR_BUILD_TARGET=X86_32 \
-DWAMR_BUILD_AOT=1 \
-DWAMR_BUILD_WAMR_COMPILER=0 \
-DWAMR_BUILD_INTERP=1 \
-DWAMR_BUILD_FAST_INTERP=0 \
@ -225,6 +221,7 @@ RUN apt-get update \
xorriso \
grub-pc-bin \
bochs \
less \
&& apt-get clean
COPY --from=compiler-builder /opt/crosscompiler /opt/crosscompiler
@ -235,7 +232,7 @@ RUN ln -sf /opt/wamr/product-mini/platforms/linux/build_iwasm /opt/wamr-iwasm \
&& ln -sf /opt/wamr/wamr-compiler/build_wamrc /opt/wamr-wamrc \
&& ln -sf /opt/wamr/wamr-compiler/build_libvmlib /opt/wamr-libvmlib \
&& ln -sf /opt/wamr/build_libiwasm /opt/wamr-libiwasm \
&& ln -sf /opt/wamr/build_libiwasm_64 /opt/wamr-libiwasm-64
&& ln -sf /opt/wamr/build_libiwasm_linux /opt/wamr-libiwasm-linux
COPY ./examples /home/ubuntu/examples
WORKDIR /home/ubuntu/examples