feat(v4): the machine boots from its ROM; the prebuilt nucleus is gone
The host node starts in its ROM (entry 12), and the boot feeds it the system's source through the console: capsules/v4/sys/map-64.f18, the fourteen .f18 blobs and end.f18, each found, hash-checked and signature-checked as any capsule, then EOT. The ROM assembles the system and starts it at (IDLE); the host reads the image record (v4_image_from_node) for what only the assembled system knows. A ROM error is reported with its blob, line and meaning, then PARITY:FAIL. Deleted: v4/tools/mkimage.c, capsules/v4/nucleus-64.f18, v4/capsule/*.v4, v4/tools/v4tof18.py. The .f18 files are the source now. - text.c speaks the rest of the ROM's language (set, here, store, start; v4_text_value, v4_text_start), so the oracle reads the same source: test_host_rom_nucleus compares the ROM against text.c on the .f18 files, word for word, image record included. Host tests load the .f18 files. - mkmap image writes v4_map_image (the map's description of the system); hosted and the kernel link the ROM and the map instead of v4_image_64.c. - Hera (Captain Bob's ruling, option 1): births stream the system the ROM assembled, as assembled code; hera.4th is unchanged. test_host_unit's host builds the system with the ROM. - New parity lines: PARITY:V4_F18 per blob, PARITY:V4_ROM words=2049 rom_hash=0xa6c792b5821010b7 instructions=60725216. Acceptance: amd64, aarch64, riscv64 boot to ok> with PARITY:V4_POST tests=538 pass=538 fail=0, POST: PASSED, and PARITY:V4_SYSTEM word_count=317 dict_hash=0xe5a57f3eb72ff94a on all three -- the same hash as the prebuilt nucleus gave. make -C v4 test test-32 hosted-check: all pass. Logs: logs/20261015-141648, -141938, -142350. Startup cost under QEMU TCG, the ROM's assembly (last V4_F18 line to V4_ROM): amd64 26.7 s of 132 s to ok>; aarch64 41.0 s of 195 s; riscv64 20.5 s of 101 s. Hosted native: +0.85 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1bf19d6224
commit
a73580e949
@@ -13,6 +13,7 @@
|
||||
#include "v4/testcode.h"
|
||||
#include "host_map.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if V4_CELL_BITS == 64
|
||||
@@ -84,9 +85,13 @@ static int rom_in(const v4_node *n, const char *name)
|
||||
return (long)n->p >= start && (long)n->p < next;
|
||||
}
|
||||
|
||||
static char *rom_system_text(size_t *len);
|
||||
static int rom_build_system(v4_node *n, long *words);
|
||||
|
||||
/* Reset `n`, attach the ROM and the console's receive registers. */
|
||||
static void rom_boot(v4_node *n)
|
||||
{
|
||||
(void)rom_build_system;
|
||||
(void)host_load; /* host_map.h's loader is not used here */
|
||||
(void)host_branch_slots;
|
||||
(void)rom_call; /* not every test uses every helper */
|
||||
@@ -99,4 +104,61 @@ static void rom_boot(v4_node *n)
|
||||
v4_node_console_input_attach(n, CONSOLE_RX, CONSOLE_ST);
|
||||
}
|
||||
|
||||
/* THE SYSTEM, AS THE MACHINE BUILDS IT (MACHINE.md section 6, step 1). The
|
||||
* system's source, capsules/v4/sys (V4_SYS_DIR): the map, the fourteen and
|
||||
* the end, each followed by a new line, then EOT -- what v4/system/boot.c
|
||||
* feeds the console. rom_system_text gives it whole, *len its length;
|
||||
* rom_build_system has `n`, booted with its ROM, assemble it, and runs it to
|
||||
* its start: 1 if it started, with *words the instruction words it took. */
|
||||
static const char *const rom_system_files[] = { "core", "input", "dict", "codegen", "compile", "quit", "forth",
|
||||
"numout", "words", "system", "qmath", "blocks", "log", "acl" };
|
||||
|
||||
static char *rom_system_text(size_t *len)
|
||||
{
|
||||
size_t total = 0, cap = 1u << 20;
|
||||
char *text = malloc(cap);
|
||||
unsigned i;
|
||||
if (!text) return NULL;
|
||||
for (i = 0; i < 16; i++) {
|
||||
char path[512];
|
||||
FILE *f;
|
||||
long n;
|
||||
if (i == 0) snprintf(path, sizeof path, "%s/map-%d.f18", V4_SYS_DIR, V4_CELL_BITS);
|
||||
else if (i <= 14) snprintf(path, sizeof path, "%s/%s.f18", V4_SYS_DIR, rom_system_files[i - 1]);
|
||||
else snprintf(path, sizeof path, "%s/end.f18", V4_SYS_DIR);
|
||||
f = fopen(path, "rb");
|
||||
if (!f) { printf(" cannot read %s\n", path); free(text); return NULL; }
|
||||
fseek(f, 0, SEEK_END); n = ftell(f); fseek(f, 0, SEEK_SET);
|
||||
if (n < 0 || total + (size_t)n + 2 > cap || fread(text + total, 1, (size_t)n, f) != (size_t)n) {
|
||||
fclose(f); free(text); return NULL;
|
||||
}
|
||||
fclose(f);
|
||||
total += (size_t)n;
|
||||
text[total++] = '\n'; /* a blob that does not end with a new line still ends a token */
|
||||
}
|
||||
text[total++] = 4; /* EOT */
|
||||
*len = total;
|
||||
return text;
|
||||
}
|
||||
|
||||
static int rom_build_system(v4_node *n, long *words)
|
||||
{
|
||||
size_t total, fed = 0;
|
||||
char *text = rom_system_text(&total);
|
||||
long w = 0;
|
||||
if (!text) return 0;
|
||||
rom_boot(n);
|
||||
v4_node_stack_regs_attach(n, DSTACK_REG, RSTACK_REG);
|
||||
n->p = V4_ROM_BASE + 12; /* entry 12, (ROM): where the machine starts */
|
||||
while (n->p >= V4_ROM_BASE && w < 400000000L && !n->stopped) {
|
||||
if (fed < total && n->input_pos == n->input_len) fed += v4_node_console_feed(n, text + fed, (unsigned)(total - fed));
|
||||
(void)v4_exec_step_word(n, &rom_es, &rom_h);
|
||||
w++;
|
||||
if (w % 1000 == 0 && n->mem[ROM_FAILED] != 0) break;
|
||||
}
|
||||
free(text);
|
||||
if (words) *words = w;
|
||||
return n->p < V4_ROM_BASE && n->mem[ROM_FAILED] == 0;
|
||||
}
|
||||
|
||||
#endif /* V4_TESTS_ROM_HARNESS_H */
|
||||
|
||||
Reference in New Issue
Block a user