118 lines
3.7 KiB
Markdown
118 lines
3.7 KiB
Markdown
# 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`](../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:
|
|
|
|
```bash
|
|
sudo apt-get install -y \
|
|
gcc-aarch64-linux-gnu \
|
|
gcc-riscv64-linux-gnu \
|
|
qemu-user qemu-user-static
|
|
```
|
|
|
|
---
|
|
|
|
## amd64 — native
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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:
|
|
|
|
```c
|
|
#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.
|