feat(v4.0.0): every node asks the kernel for its blocks; a born node is not POSTed

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>
This commit is contained in:
rajames
2026-10-07 08:24:47 -04:00
co-authored by Claude Opus 5.5
parent 26a0748455
commit d5b7235464
34 changed files with 953 additions and 725 deletions
+21 -12
View File
@@ -4,9 +4,12 @@
\ EMPTY-BUFFERS LIST LOAD SCR BLK, and v3's FLUSH THRU and --> . Part of the
\ compiler capsule; rests on everything before it.
\
\ THE DEVICE (D-19) is four registers: the block's number, the word address
\ of 256 cells, a command -- 1 read, 2 write -- and a status that is 0 when
\ the command worked.
\ STORAGE IS THE KERNEL'S (docs/v4.0.0/MESH.md section 8, ENGINE.md 3.3). A
\ node only ever asks for a block by number, and it asks its kernel: with
\ the number and the word address of 256 cells on the data stack it writes
\ the request to port 0, where its kernel is, and when the write has been
\ served the status is on the stack in their place -- 0 it worked, 2 it was
\ refused, 3 there is no such block.
\
\ THE BUFFERS. There are two, of 256 cells each, so two blocks can be in
\ memory at once -- one can be copied to another. A buffer is given to the
@@ -15,7 +18,7 @@
\ and TIB are: what C@ CMOVE and TYPE take.
\
\ Constants the loader supplies:
\ BLOCK-NUMBER BLOCK-ADDRESS BLOCK-COMMAND BLOCK-STATUS the device
\ BLOCK-READ# BLOCK-WRITE# the numbers of the kernel's two requests
\ BUF0 BUF1 word addresses of the two buffers
\ (B) word address of six cells: (B)+0 the block in buffer 0, or 0
\ (B)+1 whether it has been UPDATEd (B)+2 (B)+3 the same for
@@ -30,15 +33,21 @@ header BLK inline : BLK' BLK ;
\ ( i -- addr ) the word address of buffer i, where i is 0 or 2
: (BUF) if Z drop BUF1 ; Z: drop BUF0 ;
\ ( command i -- ) read or write buffer i's block. A block the device
\ does not have is an error (code 13); the buffer is then empty.
\ ( command i -- ) read buffer i's block from storage, command 1, or
\ write it, command 2: a request of this node's kernel ( n waddr -- status ).
\ If it did not work nothing is in the buffer, and it is an error: 17 if
\ storage refused, 13 if there is no such block.
: (DEVICE)
dup (B) + a! @ BLOCK-NUMBER b! !b \ command i
dup (BUF) BLOCK-ADDRESS b! !b
push BLOCK-COMMAND b! !b pop \ i
BLOCK-STATUS b! @b if FINE
drop (B) + a! 0 !+ 0 ! \ nothing is in the buffer
NODE-ERROR b! 13 !b ;
dup push SWAP push \ i R: i command
dup (B) + a! @ SWAP (BUF) \ n waddr
pop -1 + if RD drop BLOCK-WRITE# jump ASK
RD: drop BLOCK-READ#
ASK: (PORT) b! !b \ status
pop SWAP \ i status
if FINE
push (B) + a! 0 !+ 0 ! pop
-2 + if E17 drop NODE-ERROR b! 13 !b ;
E17: drop NODE-ERROR b! 17 !b ;
FINE: drop drop ;
\ ( i -- ) if buffer i's block has been UPDATEd, write it
+1
View File
@@ -20,6 +20,7 @@
\ 11 Division by zero (Q./) 12 Argument out of range
\ 13 Block out of range 14 No block is being loaded
\ 15 Deferred word not set 16 Not a word
\ 17 Storage refused
\ -1 the word has printed its own message
macro SWAP over push push drop pop pop endmacro
+2 -1
View File
@@ -297,7 +297,7 @@ header ABORT
POS: -1 + if M1 -1 + if M2 -1 + if M3 -1 + if M4
-1 + if M5 -1 + if M6 -1 + if M7 -1 + if M8 -1 + if M9
-1 + if M10 -1 + if M11 -1 + if M12 -1 + if M13 -1 + if M14
-1 + if M15 -1 + if M16
-1 + if M15 -1 + if M16 -1 + if M17
drop 2 jump (DONE)
M1: drop $6167654E (EMIT4) $65766974 (EMIT4) $756F6320 (EMIT4) $746E (EMIT4) CR 2 jump (DONE)
M2: drop $20746F4E (EMIT4) $756E2061 (EMIT4) $7265626D (EMIT4) CR 2 jump (DONE)
@@ -315,6 +315,7 @@ header ABORT
M14: drop $62206F4E (EMIT4) $6B636F6C (EMIT4) $20736920 (EMIT4) $6E696562 (EMIT4) $6F6C2067 (EMIT4) $64656461 (EMIT4) CR 2 jump (DONE)
M15: drop $65666544 (EMIT4) $64657272 (EMIT4) $726F7720 (EMIT4) $6F6E2064 (EMIT4) $65732074 (EMIT4) $74 (EMIT4) CR 2 jump (DONE)
M16: drop $20746F4E (EMIT4) $6F772061 (EMIT4) $6472 (EMIT4) CR 2 jump (DONE)
M17: drop $726F7453 (EMIT4) $20656761 (EMIT4) $75666572 (EMIT4) $646573 (EMIT4) CR 2 jump (DONE)
\ The table the loader gives the node: six words, one for each kind of
\ fault in the node's order, each a jump. A jump fills its word, so they