Files
LithosAnanake/docs/lithosananke/hosted-acceptance-test/README.md
T

3.7 KiB

Hosted StarForth — 3-Architecture Acceptance Test

Date: 2026-07-24 Branch: lithosananke Commit: edced063 (block-subsystem buffer-sizing fix that made this pass on all three architectures)


What this verifies

The hosted StarForth VM (make, not Makefile.starkernel) is a static binary. This test confirms it starts cleanly — reaches the ok> REPL prompt with no errors — on all three architectures the project targets:

  • amd64 — native execution on the build host
  • aarch64 — cross-compiled, run under QEMU user-mode emulation
  • riscv64 — cross-compiled, run under QEMU user-mode emulation

This is distinct from the kernel (Makefile.starkernel) 3-arch acceptance test documented in ../amd64-isr-fix/README.md, which boots a full UEFI bare-metal image under system-mode QEMU. This test only exercises the hosted Linux binary, using QEMU user-mode emulation (qemu-aarch64-static / qemu-riscv64-static) to run a foreign-architecture static binary directly on the x86_64 host — no kernel, no UEFI firmware, no system emulation.


Prerequisites

Cross toolchains and QEMU user-mode emulators:

sudo apt-get install -y \
    gcc-aarch64-linux-gnu \
    gcc-riscv64-linux-gnu \
    qemu-user qemu-user-static

amd64 — native

make clean && make
./build/amd64/standard/starforth -c "1 2 + . BYE"

Expect 3 printed and a clean exit. No emulation needed — this is the build host's native architecture.


aarch64 — cross-compile + QEMU user-mode

make rpi4-cross
qemu-aarch64-static ./build/raspi/fastest/starforth -c "1 2 + . BYE"

make rpi4-cross cross-compiles with aarch64-linux-gnu-gcc (ARCH=raspi, TARGET=fastest, -static); see Makefile:547-554. The output binary is statically linked, so qemu-aarch64-static can execute it directly with no sysroot.


riscv64 — cross-compile + QEMU user-mode

There is no dedicated make target for this yet (unlike rpi4-cross for aarch64) — invoke the cross-compile directly:

make ARCH=riscv64 CC=riscv64-linux-gnu-gcc TARGET=fastest \
    CFLAGS="-std=c99 -Wall -Werror -Iinclude -Isrc/word_source -Isrc/test_runner/include -DSTRICT_PTR=1 -march=rv64gc -mabi=lp64d -mcmodel=medany -DARCH_RISCV64=1 -O3 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DNDEBUG -flto -static" \
    LDFLAGS="-flto -s -static" \
    all

qemu-riscv64-static ./build/riscv64/fastest/starforth -c "1 2 + . BYE"

Pass criteria

For each architecture:

  1. Build completes with no errors.
  2. blk_subsys_init succeeds — no "Failed to initialize block subsystem" error. (This was broken on every architecture, including amd64, prior to edced063 — see below.)
  3. 1 2 + . BYE prints 3 and exits cleanly, or an interactive run reaches the ok> prompt.

Background: the block-subsystem bug this depends on

Before edced063, the hosted VM could not start on any architecture on this branch. src/main.c allocated a hardcoded blk_ram[1024 * 1024] buffer, stale relative to BLK_RAM_BLOCKS=2080 (include/block_subsystem.h) — a deliberate redesign that moved the RAM/ramdrive boundary to physical block 2080 (user-visible LBN 2048), per BLK_FORTH_SYS_RESERVED=32. The kernel-side buffer in src/starkernel/vm/bootstrap/sk_vm_bootstrap.c already derived its size correctly from the shared constant; main.c was the one remaining hardcoded holdout. The fix:

#include "block_subsystem.h"
...
static uint8_t blk_ram[BLK_RAM_BLOCKS * BLK_FORTH_SIZE];   /* was: blk_ram[1024 * 1024] */

This is why the acceptance test above is meaningful on lithosananke specifically: it did not pass before this fix, on any of the three architectures.