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
+14
-28
@@ -7,8 +7,12 @@
|
||||
* kernel --0 | / \ | square; the corners across from each
|
||||
* [13]---[14] other are not wired
|
||||
*
|
||||
* Hera is born empty and is given the nucleus through the port her requests
|
||||
* go to, as the boot gives it (v4/system/boot.c). She is told who she is,
|
||||
* The host builds the system as the machine does: a node with its ROM
|
||||
* assembles capsules/v4/sys (MACHINE.md section 6, step 1; tests/
|
||||
* rom_harness.h). That system, assembled, is the nucleus capsule: a node
|
||||
* that is born is given assembled code, never the source (Captain Bob,
|
||||
* 2026-10-15). Hera is born empty and is given it through the port her
|
||||
* requests go to. She is told who she is,
|
||||
* given the words that ask for nodes (v4/include/v4/manage.h), FORTH-79,
|
||||
* POST, and her own capsule, capsules/v4/hera.4th. Then she is told
|
||||
* `10 UNIT`, and everything after that is hers: she asks for four nodes,
|
||||
@@ -16,7 +20,7 @@
|
||||
* joins them and then FORTH-79 and POST a line at a time, and joins them.
|
||||
*
|
||||
* What stands in here for the host: the capsules are read from the files
|
||||
* the build bakes in, and the nucleus is assembled as mkimage assembles it.
|
||||
* the build bakes in.
|
||||
*
|
||||
* STORAGE (MESH.md section 8, acceptance 3). Every node asks its kernel
|
||||
* for its blocks, on its port 0, and the kernel's block subsystem
|
||||
@@ -38,14 +42,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "host_map.h"
|
||||
#include "rom_harness.h"
|
||||
|
||||
static int failures = 0, checks = 0;
|
||||
#define CHECK(c,...) do{checks++; if(!(c)){failures++; printf("FAIL %s:%d: ",__FILE__,__LINE__); printf(__VA_ARGS__); printf("\n");}}while(0)
|
||||
|
||||
#define PLACES 10u
|
||||
static v4_text tx;
|
||||
static v4_node nucleus; /* the nucleus, assembled: what the capsule of F18 code is written from */
|
||||
static v4_node nucleus; /* the system, as the ROM assembled it: what the capsule of F18 code is written from */
|
||||
static v4_cell w_idle, w_fault;
|
||||
static v4_fabric_node pool[PLACES];
|
||||
static int pool_used[PLACES];
|
||||
@@ -369,28 +372,11 @@ int main(void)
|
||||
return 0;
|
||||
}
|
||||
CHECK(storage_made(), "the kernel's blocks are there before any node is");
|
||||
{
|
||||
static const char *const files[] = { "core.v4", "input.v4", "dict.v4", "codegen.v4", "compile.v4", "quit.v4", "forth.v4",
|
||||
"numout.v4", "words.v4", "system.v4", "qmath.v4", "blocks.v4", "log.v4", "acl.v4" };
|
||||
CHECK(host_load(&tx, &nucleus, files, 14), "the nucleus assembles");
|
||||
}
|
||||
CHECK(v4_text_finish(&tx), "everything is defined: %s", v4_text_error(&tx));
|
||||
CHECK(rom_build_system(&nucleus, 0), "the host's machine assembles the system with its ROM");
|
||||
if (failures) { printf(" %d checks, %d failures\n", checks, failures); return 1; }
|
||||
w_idle = v4_text_word(&tx, "(IDLE)");
|
||||
w_fault = v4_text_word(&tx, "(FAULTS)");
|
||||
nucleus.mem[DP] = DICT_W * 4; /* the variables, as at switch-on (tools/mkimage.c) */
|
||||
nucleus.mem[LATEST] = v4_text_latest(&tx);
|
||||
nucleus.mem[CFP] = CFS_W;
|
||||
nucleus.mem[BASE] = 10;
|
||||
nucleus.mem[FENCE] = DICT_W;
|
||||
nucleus.mem[BOOT_CELLS] = nucleus.mem[DP];
|
||||
nucleus.mem[BOOT_CELLS + 1] = nucleus.mem[LATEST];
|
||||
nucleus.mem[LOG_LEVEL] = 2;
|
||||
nucleus.mem[CONTEXT] = LATEST;
|
||||
nucleus.mem[CURRENT] = LATEST;
|
||||
nucleus.mem[SRC] = TIB;
|
||||
nucleus.mem[LINE_STATUS] = 1;
|
||||
HOST_MESSAGES_EMPTY(&nucleus);
|
||||
w_idle = nucleus.mem[ROM_IMG]; /* the image record (capsules/v4/sys/end.f18) */
|
||||
w_fault = nucleus.mem[ROM_IMG + 1];
|
||||
CHECK(nucleus.p == w_idle, "and it has started where it waits");
|
||||
(void)v4_capsule_write(&nucleus, w_idle, f18_put, 0);
|
||||
CHECK(f18_count > 1000 && f18_count < sizeof f18 / sizeof f18[0], "the nucleus is a capsule of F18 code: %u cells", f18_count);
|
||||
memset(&im, 0, sizeof im);
|
||||
@@ -437,7 +423,7 @@ int main(void)
|
||||
CHECK(hera->mem[DP] == before[DP] && hera->mem[LATEST] == before[LATEST], "HERE and LATEST are where they were before POST");
|
||||
for (k = 0; k < here; k++) if (hera->mem[k] != before[k]) { if (first < 0) first = k; changed++; }
|
||||
/* What differs is the TTL in the entry of each word POST had interpreted: a count of uses left before
|
||||
* the word's access is checked again, which every use counts down (compile.v4, (ACL?)), as in v3. */
|
||||
* the word's access is checked again, which every use counts down (compile.f18, (ACL?)), as in v3. */
|
||||
printf(" after POST and COLD: %ld of the %ld cells below HERE differ from before POST (the first at %ld); dict_hash %s\n",
|
||||
(long)changed, (long)here, (long)first, v4_image_dict_hash(hera, &im) == hash ? "the same" : "differs");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user