ci: boot the R49 ROM on narvi-1 instead of the conformance suite 712ea2b4d346
The conformance job of the first run on narvi-1 (run #1) never reached
the emulator; every test was skipped with
emulator control port never came up: <urlopen error [Errno 97]
Address family not supported by protocol>
The syscall tier's seccomp filter refuses every socket family but
AF_UNIX, network "loopback" or not, so no job there can talk TCP to
127.0.0.1, and the suite is HTTP on a loopback port. The build job
passed (129 s).
In its place a boot job takes the built binary, boots the R49 ROM
headless and has BASIC run a pasted program that prints
SUM 333833500, read back through -echo: the 65C02 core, VERA's timing,
the KERNAL and BASIC working on riscv64, with no network. The image now
carries the ROM at /opt/x16rom, from the emulator's R49 release (the zip
and the ROM checked against their SHA-256; the ROM is the same file as
the repository's rom.bin), and is pinned as
cas://blob/127605eab9812e79d7c80d99e012105ca12dc7060bec8bffb81576660981c157.
Python and pytest stay in it for the suite, for when the tier allows it.
The suite passes 22/22 run by hand on narvi.
- Author
- Andy McCall @andymccall <[email protected]>
- via
- agent
agent:claude@andymccall <[email protected]> · keyless, under your grant for changes,refs,seal · key ee5caabc7ed3
- When
- · 2026-10-21 03:06 UTC
- Signature
- ◈ sealed by agent:claude@andymccall
- Hash
712ea2b4d3463dfffafa6ec39721181afc825a9f5fcee0f9d6532678e3147ebe- Depends on
- a673804c781c
- Depended on by
- 10b68259f181
- In bookmarks
- main riscv-1
- Edits
- 14 atoms, 2 tree operations, 4 files
Browse the tree at this change
added .flow/jobs/boot.sh +20 −0
| 1 | + | # The x16emu the build job made on narvi-1 boots the R49 ROM (in the image |
|
| 2 | + | # at /opt/x16rom) headless, to BASIC, and runs a program pasted in, which |
|
| 3 | + | # prints a sum that only right arithmetic gives: the 65C02 core, VERA's |
|
| 4 | + | # timing, the KERNAL and BASIC all working on riscv64. -echo copies what |
|
| 5 | + | # BASIC prints to stdout. |
|
| 6 | + | set -eu |
|
| 7 | + | chmod +x x16emu |
|
| 8 | + | printf '10 S=0:FOR I=1 TO 1000:S=S+I*I:NEXT\n20 PRINT "SUM";S\n' >/tmp/sum.bas |
|
| 9 | + | SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \ |
|
| 10 | + | ./x16emu -rom /opt/x16rom/rom.bin -bas /tmp/sum.bas -run -echo -warp >/tmp/echo.txt 2>&1 & |
|
| 11 | + | emu=$! |
|
| 12 | + | i=0 |
|
| 13 | + | while ! grep -q "SUM 333833500" /tmp/echo.txt && [ $i -lt 120 ]; do |
|
| 14 | + | sleep 1 |
|
| 15 | + | i=$((i + 1)) |
|
| 16 | + | done |
|
| 17 | + | kill $emu 2>/dev/null || true |
|
| 18 | + | tr -cd '[:print:]\n' </tmp/echo.txt |
|
| 19 | + | grep -q "SUM 333833500" /tmp/echo.txt || { echo "boot: BASIC did not print SUM 333833500 within ${i} s"; exit 1; } |
|
| 20 | + | echo "boot: BASIC ran on $(uname -m) in ${i} s" |
removed .flow/jobs/conformance.sh +0 −0
| … | 28 unchanged lines |
modified .flow/image/build-riscv64.sh +11 −3
| … | 15 unchanged lines |
||
| 16 | 16 | release=24.04.5 |
|
| 17 | 17 | base=ubuntu-base-$release-base-riscv64.tar.gz |
|
| 18 | 18 | sha256=651c516f291259ec913caa1efd0cfff738cd223adfc6617c884f07af487f08cf |
|
| 19 | - | # What the Makefile and the conformance suite need, as README.md lists for |
|
| 20 | - | # riscv64 Linux: C11 and C++17 compilers, make, SDL2 and zlib, Python and |
|
| 21 | - | # pytest. |
|
| 19 | + | # What the Makefile needs, as README.md lists for riscv64 Linux: C11 and |
|
| 20 | + | # C++17 compilers, make, SDL2 and zlib; and Python with pytest for the |
|
| 21 | + | # conformance suite, once the syscall tier lets a job use loopback TCP. |
|
| 22 | 22 | packages="build-essential make libsdl2-dev zlib1g-dev python3 python3-pytest" |
|
| 23 | 23 | ||
| 24 | 24 | test "$(uname -m)" = riscv64 || { echo "build-riscv64.sh: run this on a riscv64 machine" >&2; exit 1; } |
|
| … | 20 unchanged lines |
||
| 45 | 45 | apt-get clean |
|
| 46 | 46 | rm -rf /var/lib/apt/lists/*" |
|
| 47 | 47 | sudo umount "$root/proc" "$root/dev" |
|
| 48 | + | # The R49 ROM, from the emulator's own R49 release, for the boot job: the |
|
| 49 | + | # zip and the ROM in it both checked against their SHA-256. |
|
| 50 | + | r49=https://github.com/X16Community/x16-emulator/releases/download/r49/x16emu_linux-x86_64-r49.zip |
|
| 51 | + | curl -fsSL -o "$work/r49.zip" "$r49" |
|
| 52 | + | echo "efb2d4ad36ae4244370004891aa67bdf85d2ec01b42b7f12f97b48b62aff009d $work/r49.zip" | sha256sum -c - >/dev/null |
|
| 53 | + | python3 -c 'import sys, zipfile; open(sys.argv[2], "wb").write(zipfile.ZipFile(sys.argv[1]).read("rom.bin"))' "$work/r49.zip" "$work/rom.bin" |
|
| 54 | + | echo "b81654cc8c87ed96e3ffc7c8e7c312c9f3b7b870c7bb34de61e61eac931b819a $work/rom.bin" | sha256sum -c - >/dev/null |
|
| 55 | + | sudo install -D -m 0644 "$work/rom.bin" "$root/opt/x16rom/rom.bin" |
|
| 48 | 56 | sudo rm "$root/etc/resolv.conf" |
|
| 49 | 57 | sudo mv "$work/resolv.conf.image" "$root/etc/resolv.conf" 2>/dev/null || true |
|
| 50 | 58 | sudo tar -C "$root" -cf "$out" . |
|
| … | 2 unchanged lines |
modified .flow/pipeline.kdl +18 −20
| 1 | 1 | // x16emu's pipeline on OxygenFlow: every push to a bookmark on OxygenHub |
|
| 2 | - | // builds the emulator natively on narvi-1, a real riscv64 board, and runs |
|
| 3 | - | // the control-API conformance suite against what it built. The jobs appear |
|
| 4 | - | // as checks on the change and in the Flow tab. The retro-remote-debug- |
|
| 5 | - | // controller subrepo (src/extern) is put in the workspace by the runner. |
|
| 2 | + | // builds the emulator natively on narvi-1, a real riscv64 board, and boots |
|
| 3 | + | // what it built to BASIC. The jobs appear as checks on the change and in the |
|
| 4 | + | // Flow tab. The retro-remote-debug-controller subrepo (src/extern) is put in |
|
| 5 | + | // the workspace by the runner. |
|
| 6 | + | // |
|
| 7 | + | // The control-API conformance suite (.github/workflows/conformance.yml on |
|
| 8 | + | // x86) is not run here: it talks to the emulator over TCP on 127.0.0.1, and |
|
| 9 | + | // the syscall tier refuses every socket family but AF_UNIX, even with |
|
| 10 | + | // network "loopback". It passes 22/22 run by hand on narvi. |
|
| 6 | 11 | schema-version 1 |
|
| 7 | 12 | ||
| 8 | - | // Ubuntu 24.04 riscv64 with gcc, make, SDL2, zlib, Python and pytest |
|
| 13 | + | // Ubuntu 24.04 riscv64 with gcc, make, SDL2, zlib and the R49 ROM |
|
| 9 | 14 | // (.flow/image/build-riscv64.sh), in the syscall tier: narvi's Ky X1 has no |
|
| 10 | 15 | // hardware virtualisation, so no microVM. `runs-on` keeps it on a RISC-V |
|
| 11 | - | // runner. Loopback only: the suite talks to the emulator on 127.0.0.1. |
|
| 16 | + | // runner. |
|
| 12 | 17 | sandbox "x16-riscv64" { |
|
| 13 | 18 | runtime "syscall" |
|
| 14 | - | rootfs "cas://blob/a1405289def4850dade956ea6d4e4870a73bb631cc353f16f0e5fcd796fe2541" |
|
| 19 | + | rootfs "cas://blob/127605eab9812e79d7c80d99e012105ca12dc7060bec8bffb81576660981c157" |
|
| 15 | 20 | runs-on "riscv64" |
|
| 16 | 21 | memory-limit "2GiB" |
|
| 17 | 22 | cpu-limit 6 |
|
| 18 | - | network "loopback" |
|
| 23 | + | network "isolated" |
|
| 19 | 24 | } |
|
| 20 | 25 | ||
| 21 | 26 | // make as README.md gives it, -Werror included; the binary is kept with the |
|
| 22 | - | // runner's signed receipt and handed to the conformance job. |
|
| 27 | + | // runner's signed receipt and handed to the boot job. |
|
| 23 | 28 | job "build" { |
|
| 24 | 29 | sandbox "x16-riscv64" |
|
| 25 | 30 | timeout "30m" |
|
| … | 5 unchanged lines |
||
| 31 | 36 | } |
|
| 32 | 37 | } |
|
| 33 | 38 | ||
| 34 | - | // The conformance suite (src/extern/retro-remote-debug-controller) against |
|
| 35 | - | // that binary, headless; pytest's JUnit XML for the hub's Tests tab. |
|
| 36 | - | job "conformance" { |
|
| 39 | + | // That binary boots the R49 ROM headless and runs a BASIC program. |
|
| 40 | + | job "boot" { |
|
| 37 | 41 | sandbox "x16-riscv64" |
|
| 38 | 42 | depends-on "build" |
|
| 39 | - | timeout "15m" |
|
| 43 | + | timeout "10m" |
|
| 40 | 44 | input { |
|
| 41 | 45 | artifact "x16emu-linux-riscv64" from "build" |
|
| 42 | 46 | path "/src/x16emu" |
|
| 43 | 47 | } |
|
| 44 | - | exec "sh" "-eu" ".flow/jobs/conformance.sh" |
|
| 45 | - | output { |
|
| 46 | - | artifact "junit" { |
|
| 47 | - | path "/src/junit.xml" |
|
| 48 | - | when "always" |
|
| 49 | - | } |
|
| 50 | - | } |
|
| 48 | + | exec "sh" "-eu" ".flow/jobs/boot.sh" |
|
| 51 | 49 | } |