Phase 8 C (4/n): metadata fence allocator integration + zone I/O

Corrected meta_fence_blocks units from "Forth 1 KiB blocks" to 4 KiB
devblocks (matching bam_devblocks/reloc_devblocks) before anything
depended on the original meaning -- a clean fix, not a migration. This
let the fence fold directly into compute_totals_from_B()'s existing
payload4k formula (total_devblocks - 1 - B - R - F) instead of a
separate user_blocks subtraction: total_blocks/user_blocks/free_blocks
all shrink correctly for free, in both the fresh-format and reload
paths, from one formula change.

New blk_meta_zone_read()/blk_meta_zone_write() -- raw, unpacked 4 KiB
devblock I/O, same shape as the header/BAM/reloc-table regions,
addressed by devblock_from_top counting down from the device's last
physical devblock. Refuses rather than clamps if the index exceeds the
on-disk meta_fence_blocks. C-only, no FORTH word wraps either -- same
discipline as vm_zuse_cert_install(), which will be this zone's first
real tenant.

Verified independently at every step, never trusting the kernel's own
report: capacity math cross-checked against a from-scratch Python
recomputation of the same formula (exact match); accessor correctness
via a temporary probe (written/run/captured/reverted) that wrote a
known pattern and read it back, then independently confirmed via a raw
read of the disk image at the exact expected physical byte offset.
Full 3-arch acceptance boot against the real, untouched disk/artemis.img,
probe code fully reverted -- clean, conservation intact.

Still open: wiring vm_zuse_cert_install() to actually persist through
these accessors, and the MINT word itself. Documented in FABRIC-3.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U14ET9CWAtbQMbYqomKgXd
This commit is contained in:
Robert Allan James
2026-08-26 19:40:43 -04:00
co-authored by Claude Sonnet 5
parent 2035ebeac0
commit 6e9c1d3bc2
12 changed files with 54356 additions and 19 deletions
+37 -3
View File
@@ -570,9 +570,43 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
fresh format writes `meta_fence_blocks=128` at header byte offset 184; a second boot without
reformatting reads it back unchanged; the pre-existing old-format image correctly reads back
0. Full 3-arch acceptance boot against the real, untouched `disk/artemis.img` also clean —
conservation intact, no panics. The allocator (`user_blocks` math) still doesn't know about
this reservation yet, and there are no read/write accessors for the zone's actual data —
both still open, next steps.
conservation intact, no panics.
**Step 2 (allocator + read/write accessors), done 2026-08-26.** Units corrected from "Forth
1 KiB blocks" to 4 KiB devblocks (matching `bam_devblocks`/`reloc_devblocks`) before anything
depended on the original meaning — a clean fix, not a migration, since nothing consumed the
field yet. This let the fence fold directly into `compute_totals_from_B()`'s existing
`payload4k` calculation (`total_devblocks - 1 - B - R - F`, F = `meta_fence_blocks`) instead
of needing a second, separate subtraction against `user_blocks` — `total_blocks`,
`user_blocks`, and `free_blocks` all shrink correctly for free, in both the fresh-format and
reload code paths, from this one formula change.
New `blk_meta_zone_read()`/`blk_meta_zone_write()` (`block_subsystem.c`/`.h`) — raw, unpacked
4 KiB devblock I/O (no Forth-block packing, same shape as the header/BAM/reloc-table
regions), addressed by `devblock_from_top` counting down from the device's last physical
devblock, refusing (not silently clamping) if the index isn't within the on-disk
`meta_fence_blocks`. No FORTH word wraps either — C-only, same discipline as
`vm_zuse_cert_install()` itself, which will be this zone's first real tenant.
**Verified independently at every step, never trusting the kernel's own report:**
- Capacity math: read a freshly-formatted image's header bytes directly and independently
recomputed the expected `total_blocks` in a separate Python script using the same formula
— exact match (22647, down from what it would have been without the fence).
- Accessor correctness: a temporary probe (written, run, captured, reverted) wrote a known
256-byte-repeating pattern via `blk_meta_zone_write(0, ...)`, read it back via
`blk_meta_zone_read(0, ...)`, and compared in-memory (`PASS`) — then, independently,
read the raw image file at the exact expected physical byte offset
(`(total_devblocks-1)*4096`) and confirmed the pattern landed there byte-for-byte.
- `log_message(LOG_INFO, ...)` still doesn't reach serial output in this build (same
pre-existing gap noted in Step 1) — all verification here used `console_println` (which
does reach serial) for the temporary probe, and direct file reads for everything else.
Full 3-arch acceptance boot (real, untouched `disk/artemis.img`, probe code fully reverted)
clean on all three architectures — conservation intact, no panics.
**Still open:** wiring `vm_zuse_cert_install()`'s seed+pubkey to actually persist through
these new accessors (the zone exists and works; nothing writes Zuse's cert into it yet), and
the `MINT` word itself.
### From FABRIC-2.md §X, Milestone 5 — Console/VM key-match binding