A block is a kernel request, as ENGINE.md 3.3 has it: the node puts the
block's number and the address of 256 cells on its stack and writes the
request to port 0, and the kernel leaves the status there. The requests
are -1, read, and -2, write, the same for every node. v4/system/blocks.c
serves them from the kernel's block subsystem, which is v3's. The four
storage registers are gone from the engine.
The device that spoke block messages (4a505a15) is withdrawn with its
test and its message types: Captain Bob ruled on 2026-10-07 that it, a
node's own drive, and nodes with no storage had left the OS as designed
(docs/v4.0.0/MESH.md 8.5).
Hera no longer sends POST to the nodes she births: POST is the kernel's,
once. Every node has its kernel on port 0; it serves a node's blocks and,
for Hera alone, her requests for nodes and capsules.
Bare metal: the node boots and is POSTed against POST's own block RAM,
and the kernel's chain -- fast RAM, the ramdrive, the virtio disk -- is
set up after POST and before the prompt, as on the v3 path. The disk is
read and not written: nothing in v4 yet gives the owner's word that it
may be formatted. A hosted program has the chain's fast RAM, as hosted
v3 has with no disk. Error 17 is Storage refused.
make -C v4 test and sanitize pass at both widths; hosted-check passes on
three ISAs; amd64, aarch64 and riscv64 boot, POST 538 of 538, with the
typed session: logs/20261007-081603, -081839, -082226. The hashes are
the same on all six.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
85 lines
3.6 KiB
C
85 lines
3.6 KiB
C
/* image.h -- the StarForth nucleus, as its host knows it: where things are
|
|
* in a node that has taken it in, and how a line is handed to that node.
|
|
*
|
|
* The nucleus is text (capsule/ *.v4). tools/mkimage.c assembles it on the
|
|
* build machine and writes two things:
|
|
*
|
|
* - the nucleus as a capsule of F18 code (capsule.h), which is put into
|
|
* an empty node through its port. It is a capsule like any other: in
|
|
* the capsule directory, with a name, a hash and a signature
|
|
* (capsules/v4/nucleus-<width>.f18). docs/v4.0.0/MESH.md section 5.
|
|
* - this description of it, a C file: the addresses a host needs.
|
|
*
|
|
* A node that has taken the nucleus in is sent text as messages and sends
|
|
* back what it prints (v4/include/v4/message.h); nothing here hands it a
|
|
* line.
|
|
*
|
|
* A description is for one cell width, one node size and one pair of stack
|
|
* sizes; v4_image_born refuses one the engine was not built for.
|
|
*/
|
|
#ifndef V4_IMAGE_H
|
|
#define V4_IMAGE_H
|
|
|
|
#include "v4/exec.h"
|
|
|
|
typedef struct {
|
|
/* what the image was built for */
|
|
unsigned cell_bits, node_words, data_ring, ret_ring;
|
|
|
|
/* Where the nucleus waits for a message (v4/capsule/quit.v4, (IDLE)):
|
|
* the node's P is there, blocked reading its ports, when it has nothing
|
|
* to do. */
|
|
v4_cell idle;
|
|
v4_cell fault_table; /* (FAULTS): where a fault goes */
|
|
v4_cell port; /* word address of the node's port (node.h) */
|
|
|
|
/* KEY's code: a node whose P is in key_start .. key_end - 1 with no
|
|
* character pending is waiting for one */
|
|
v4_cell key_start, key_end;
|
|
|
|
/* the memory-mapped registers (DECOMPOSITION.md section 7; D-4 leaves
|
|
* the map to the loader, and this is the map the image was built with) */
|
|
v4_cell console_tx, console_rx, console_status;
|
|
v4_cell dstack_reg, rstack_reg;
|
|
v4_cell node_error;
|
|
|
|
/* the dictionary's two variables: DP holds HERE, a byte address, and
|
|
* LATEST the newest word of FORTH. What lies below HERE, and LATEST,
|
|
* is what the dictionary hash covers (v4/include/v4/boot.h). */
|
|
v4_cell dp, latest;
|
|
|
|
/* What COLD returns the system to and FORGET will not go below: two
|
|
* cells, DP and LATEST as they were when the system was complete, and
|
|
* the variable FENCE. The image has them as the nucleus alone; a system
|
|
* that loads capsules when it boots sets them again when it has
|
|
* (v4_image_seal). */
|
|
v4_cell boot_cells, fence;
|
|
} v4_image;
|
|
|
|
/* The description of the nucleus built from v4/capsule (the generated file
|
|
* defines it). */
|
|
extern const v4_image v4_capsule_image;
|
|
|
|
/* The system is complete: what is in the dictionary now is what COLD comes
|
|
* back to, and FORGET will not go below it. */
|
|
void v4_image_seal(v4_node *n, const v4_image *im);
|
|
|
|
/* The dictionary hash of a node started from `im`: FNV-1a over its memory
|
|
* below HERE, a cell at a time, low byte first, and then LATEST. It does
|
|
* not depend on the machine: every build of one commit, with one cell
|
|
* width, gives the same hash for the same dictionary. */
|
|
uint64_t v4_image_dict_hash(const v4_node *n, const v4_image *im);
|
|
|
|
/* A node newly born (node.h), with the registers the nucleus expects of the
|
|
* node it runs on. Its memory is empty and it is blocked
|
|
* reading its ports: the nucleus is yet to be sent to it. Returns 1, or 0
|
|
* if the description is not for this build of the engine (nothing is then
|
|
* done). */
|
|
int v4_image_born(v4_node *n, v4_exec_state *es, v4_heat *h, const v4_image *im);
|
|
|
|
/* 1 if the node is waiting for a character: it is inside KEY and none is
|
|
* pending. */
|
|
int v4_image_waiting(const v4_node *n, const v4_image *im);
|
|
|
|
#endif /* V4_IMAGE_H */
|