One boot, v4/system/boot.c, for both products: it starts the nucleus image, finds each capsule in the baked capsule directory, recomputes its hash, checks its signature, gives its blocks to the node a line at a time, and prints PARITY:V4_NUCLEUS, PARITY:V4_CAPSULE and PARITY:OK before the prompt. A line the node does not accept ends the boot with the capsule, block and line named. docs/v4.0.0/NUCLEUS.md. - hosted Linux product for amd64, aarch64 and riscv64 (make -C v4 hosted); make -C v4 hosted-check boots all three and requires identical output - the kernel's v4 entry (STARFORTH_V4=1) calls the same boot - capsules/v4/forth79.4th, block 6000: no definitions yet - mkimage builds the nucleus only; no FORTH source is compiled at build time - capsule_blocks.c: the Block-header parse, free of any VM, for every loader Verified: make -C v4 test passes; hosted-check passes on the three ISAs with the same hashes; the kernel compiles with STARFORTH_V4=1 on the three. Not verified: no bare-metal boot of v4 has been run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
49 lines
1.5 KiB
C
49 lines
1.5 KiB
C
/* hosted.c -- StarForth v4 as a Linux program: the nucleus image on the
|
|
* golden model, its capsules loaded as the system comes up (v4/include/v4/
|
|
* boot.h, the same boot the bare-metal kernel runs), the console on stdin
|
|
* and stdout.
|
|
*
|
|
* It runs until its input ends. Blocks are kept in memory and are gone
|
|
* when it stops.
|
|
*/
|
|
#include "v4/boot.h"
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
#define BLOCKS 64u
|
|
|
|
static v4_node n;
|
|
static v4_exec_state es;
|
|
static v4_heat h;
|
|
static unsigned char disk[BLOCKS * V4_BLOCK_BYTES];
|
|
|
|
static void console_out(const char *text, unsigned len)
|
|
{
|
|
(void)fwrite(text, 1, len, stdout);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
const v4_image *im = &v4_capsule_image;
|
|
unsigned char buf[256];
|
|
v4_boot boot;
|
|
|
|
boot.n = &n; boot.es = &es; boot.h = &h; boot.im = im; boot.out = console_out;
|
|
if (!v4_boot_run(&boot, disk, BLOCKS)) { fflush(stdout); return 1; }
|
|
for (;;) {
|
|
(void)v4_exec_step_word(&n, &es, &h);
|
|
if (n.console_len) {
|
|
(void)fwrite(n.console, 1, n.console_len, stdout);
|
|
n.console_len = 0;
|
|
}
|
|
if (n.stopped) { fflush(stdout); fprintf(stderr, "starforth4: the node stopped on a fault\n"); return 1; }
|
|
if (v4_image_waiting(&n, im)) {
|
|
ssize_t got;
|
|
fflush(stdout);
|
|
got = read(0, buf, sizeof buf);
|
|
if (got <= 0) { putchar('\n'); return 0; }
|
|
(void)v4_node_console_feed(&n, buf, (unsigned)got);
|
|
}
|
|
}
|
|
}
|