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
+29
-39
@@ -82,25 +82,16 @@ blocks_src = $(if $(call uses_blocks,$(1)),$(BLOCKS_SRC) $(HERE)/system/pos
|
||||
blocks_objs = $(if $(call uses_blocks,$(1)),$(BINDIR)/v3blocks.o)
|
||||
san_blocks_objs = $(if $(call uses_blocks,$(1)),$(BINDIR)/san-v3blocks.o)
|
||||
|
||||
# The capsule sources: definitions as text (include/v4/text.h), which tests
|
||||
# assemble onto a node. The directory is passed to the tests so that they
|
||||
# find the files whatever directory make was run from.
|
||||
CAPSULES := $(wildcard $(HERE)/capsule/*.v4)
|
||||
capsule_dir := -DV4_CAPSULE_DIR='"$(HERE)/capsule"'
|
||||
|
||||
# THE NUCLEUS IMAGE. tools/mkimage.c, built for the host node (HOST_WORDS
|
||||
# and the host stack sizes) at one cell width, assembles the nucleus --
|
||||
# capsule/*.v4 -- and writes it as a C file, $(BINDIR)/v4_image_<width>.c.
|
||||
# The hosted system below and the bare-metal kernel (kernel/Makefile,
|
||||
# STARFORTH_V4=1) link the 64-bit one. docs/v4.0.0/NUCLEUS.md.
|
||||
# The nucleus as a capsule of F18 code (include/v4/capsule.h). The 64-bit one
|
||||
# is a product's: it goes into the capsule directory, ../capsules/v4, where
|
||||
# the repository's mkcapsule finds it, hashes it and signs it with every
|
||||
# other capsule. It is a built file kept in the tree, as
|
||||
# ../capsules/BLOCK_MAP.md is, and is to be committed when it changes.
|
||||
# The system's source, capsules/v4/sys (MACHINE.md 3): F18 assembler as text
|
||||
# (include/v4/text.h), which the ROM assembles when the machine starts and
|
||||
# tests assemble onto a node with text.c. capsule/ holds the FORTH source
|
||||
# tests compile (*.fth). Both directories are passed to the tests so that
|
||||
# they find the files whatever directory make was run from.
|
||||
ROOT := $(abspath $(HERE)/..)
|
||||
NUCLEUS_64 := $(ROOT)/capsules/v4/nucleus-64.f18
|
||||
NUCLEUS_32 := $(BINDIR)/nucleus-32.f18
|
||||
SYS_DIR := $(ROOT)/capsules/v4/sys
|
||||
CAPSULES := $(wildcard $(SYS_DIR)/*.f18) $(wildcard $(HERE)/capsule/*.fth)
|
||||
capsule_dir := -DV4_CAPSULE_DIR='"$(HERE)/capsule"' -DV4_SYS_DIR='"$(SYS_DIR)"'
|
||||
|
||||
HOST_DEFS := -DV4_NODE_WORDS=$(HOST_WORDS) -DV4_DATA_RING=$(HOST_DATA_RING) -DV4_RET_RING=$(HOST_RET_RING) -DV4_ROM_WORDS=$(HOST_ROM_WORDS)
|
||||
ENGINE_SRCS := $(addprefix $(HERE)/src/,node.c exec.c stack.c iword.c heat.c guard.c image.c fabric.c capsule.c message.c wire.c)
|
||||
|
||||
@@ -108,17 +99,18 @@ ENGINE_SRCS := $(addprefix $(HERE)/src/,node.c exec.c stack.c iword.c heat.c gua
|
||||
# code in capsules/v4/rom, assembled off the node by tools/mkrom.c, as a
|
||||
# bitstream is built. tools/mkmap.c writes the memory map's constants it is
|
||||
# assembled with, from tests/host_map.h. main.f18 comes first: the ROM's
|
||||
# entry table is at its base. Tests named test_host_rom_*.c link the ROM of
|
||||
# entry table is at its base. Tests named test_host_rom_*.c, and
|
||||
# test_host_unit.c, whose host builds the system with it, link the ROM of
|
||||
# their width and read its symbols.
|
||||
ROM_DIR := $(ROOT)/capsules/v4/rom
|
||||
ROM_FILES := $(wildcard $(addprefix $(ROM_DIR)/,main.f18 in.f18 num.f18 sym.f18 pack.f18 word.f18 dir.f18))
|
||||
MKROM_WORDS := $(shell expr $(HOST_WORDS) + $(HOST_ROM_WORDS))
|
||||
rom_src = $(if $(findstring /test_host_rom_,$(1)),$(BINDIR)/rom-$(2).c)
|
||||
rom_sym = $(if $(findstring /test_host_rom_,$(1)),-DV4_ROM_SYM='"$(BINDIR)/rom-$(2).sym"' -DV4_SYS_DIR='"$(SYS_DIR)"')
|
||||
uses_rom = $(or $(findstring /test_host_rom_,$(1)),$(findstring /test_host_unit,$(1)))
|
||||
rom_src = $(if $(call uses_rom,$(1)),$(BINDIR)/rom-$(2).c)
|
||||
rom_sym = $(if $(call uses_rom,$(1)),-DV4_ROM_SYM='"$(BINDIR)/rom-$(2).sym"')
|
||||
# THE SYSTEM'S SOURCE as the ROM reads it (MACHINE.md 3): capsules/v4/sys. Its
|
||||
# map, map-<width>.f18, is written by tools/mkmap.c from tests/host_map.h
|
||||
# (`make sysmap`) and kept in the tree, as capsules/BLOCK_MAP.md is.
|
||||
SYS_DIR := $(ROOT)/capsules/v4/sys
|
||||
|
||||
define ROM_RULE
|
||||
$(BINDIR)/mkmap-$(1): $(HERE)/tools/mkmap.c $$(SRCS) $$(wildcard $(HERE)/include/v4/*.h) $(HERE)/tests/host_map.h $(HERE)/Makefile
|
||||
@@ -131,6 +123,9 @@ $(BINDIR)/rom-map-$(1).f18: $(BINDIR)/mkmap-$(1)
|
||||
$(SYS_DIR)/map-$(1).f18: $(BINDIR)/mkmap-$(1)
|
||||
$(BINDIR)/mkmap-$(1) sys > $$@
|
||||
|
||||
$(BINDIR)/v4_map_$(1).c: $(BINDIR)/mkmap-$(1)
|
||||
$(BINDIR)/mkmap-$(1) image > $$@
|
||||
|
||||
$(BINDIR)/mkrom-$(1): $(HERE)/tools/mkrom.c $$(SRCS) $$(wildcard $(HERE)/include/v4/*.h) $(HERE)/Makefile
|
||||
@mkdir -p $(BINDIR)
|
||||
$$(CC) $$(CFLAGS) -I$(HERE)/include -DV4_CELL_BITS=$(1) -DV4_NODE_WORDS=$(MKROM_WORDS) -DV4_DATA_RING=$(HOST_DATA_RING) -DV4_RET_RING=$(HOST_RET_RING) \
|
||||
@@ -147,23 +142,17 @@ rom: $(foreach w,$(WIDTHS),$(BINDIR)/rom-$(w).c)
|
||||
.PHONY: sysmap
|
||||
sysmap: $(foreach w,$(WIDTHS),$(SYS_DIR)/map-$(w).f18)
|
||||
|
||||
define IMAGE_RULE
|
||||
$(BINDIR)/mkimage-$(1): $(HERE)/tools/mkimage.c $$(SRCS) $$(wildcard $(HERE)/include/v4/*.h) $(HERE)/tests/host_map.h $(HERE)/Makefile
|
||||
@mkdir -p $(BINDIR)
|
||||
$$(CC) $$(CFLAGS) -I$(HERE)/include -DV4_CELL_BITS=$(1) $(HOST_DEFS) $(capsule_dir) $(HERE)/tools/mkimage.c $$(SRCS) -o $$@
|
||||
|
||||
$(BINDIR)/v4_image_$(1).c: $(BINDIR)/mkimage-$(1) $$(CAPSULES)
|
||||
$(BINDIR)/mkimage-$(1) $$@ $$(NUCLEUS_$(1))
|
||||
endef
|
||||
$(foreach w,$(WIDTHS),$(eval $(call IMAGE_RULE,$(w))))
|
||||
|
||||
# The machine as a host links it (the hosted system below, the bare-metal
|
||||
# kernel): the ROM, and the map's description of the system (include/v4/
|
||||
# image.h, v4_map_image).
|
||||
.PHONY: image
|
||||
image: $(foreach w,$(WIDTHS),$(BINDIR)/v4_image_$(w).c)
|
||||
image: $(foreach w,$(WIDTHS),$(BINDIR)/rom-$(w).c $(BINDIR)/v4_map_$(w).c)
|
||||
|
||||
# THE HOSTED SYSTEM: StarForth v4 as a Linux program, a product, for amd64,
|
||||
# aarch64 and riscv64 -- $(BINDIR)/starforth4-<isa>. It is the engine, the
|
||||
# 64-bit nucleus image, the capsule directory and the boot (system/boot.c)
|
||||
# that loads the capsules from it: the same four the kernel links. The
|
||||
# 64-bit ROM and map, the capsule directory and the boot (system/boot.c)
|
||||
# that has the ROM assemble the system's source from it and loads the
|
||||
# capsules: the same the kernel links. The
|
||||
# directory is made by the repository's own tools/mkcapsule.c from
|
||||
# ../capsules, signed if the key is on this machine (kernel/Makefile,
|
||||
# SIGN_KEY), and the code that reads it is the kernel's, compiled here as it
|
||||
@@ -183,6 +172,7 @@ CRYPTO_SRCS := $(addprefix $(ROOT)/kernel/src/crypto/,ed25519.c fe25519.c scal
|
||||
MKCAPSULE_SRCS := $(ROOT)/tools/mkcapsule.c $(ROOT)/tools/pkcs8_ed25519.c $(CRYPTO_SRCS)
|
||||
CAPSULE_FILES := $(shell find $(ROOT)/capsules -type f ! -name '.*' 2>/dev/null)
|
||||
CAPSULE_DIR_C := $(BINDIR)/capsule_generated.c
|
||||
MACHINE_64 := $(BINDIR)/rom-64.c $(BINDIR)/v4_map_64.c
|
||||
|
||||
# the kernel's capsule code: find, check the hash, verify the signature,
|
||||
# split a payload into blocks
|
||||
@@ -197,15 +187,15 @@ $(BINDIR)/mkcapsule: $(MKCAPSULE_SRCS)
|
||||
@mkdir -p $(BINDIR)
|
||||
cc -std=c99 -Wall -Wextra -O2 -I$(ROOT)/v3/include -I$(ROOT)/kernel/include -I$(ROOT)/tools -o $@ $(MKCAPSULE_SRCS)
|
||||
|
||||
$(CAPSULE_DIR_C): $(BINDIR)/mkcapsule $(CAPSULE_FILES) $(BINDIR)/v4_image_64.c
|
||||
$(CAPSULE_DIR_C): $(BINDIR)/mkcapsule $(CAPSULE_FILES)
|
||||
$(BINDIR)/mkcapsule $(SIGN_KEY_ARGS) $(ROOT)/capsules $@
|
||||
|
||||
define HOSTED_RULE
|
||||
$(BINDIR)/starforth4-$(1): $(HERE)/tools/hosted.c $(BINDIR)/v4_image_64.c $(CAPSULE_DIR_C) $$(ENGINE_SRCS) $$(SYSTEM_SRCS) $(BLOCKS_SRC) $(V3_BLOCK_SRCS) $$(wildcard $(HERE)/include/v4/*.h) $(HERE)/Makefile
|
||||
$(BINDIR)/starforth4-$(1): $(HERE)/tools/hosted.c $(MACHINE_64) $(CAPSULE_DIR_C) $$(ENGINE_SRCS) $$(SYSTEM_SRCS) $(BLOCKS_SRC) $(V3_BLOCK_SRCS) $$(wildcard $(HERE)/include/v4/*.h) $(HERE)/Makefile
|
||||
$$(CC_$(1)) $$(CFLAGS) -D_POSIX_C_SOURCE=200809L -I$(HERE)/include $(V3_INC) -DV4_CELL_BITS=64 $(HOST_DEFS) -c $(HERE)/tools/hosted.c -o $(BINDIR)/hosted-$(1).o
|
||||
@rm -rf $(BINDIR)/v3o-$(1) && mkdir -p $(BINDIR)/v3o-$(1)
|
||||
cd $(BINDIR)/v3o-$(1) && $$(CC_$(1)) $(V3_CFLAGS) -I$(HERE)/include -DV4_CELL_BITS=64 $(HOST_DEFS) -c $(V3_BLOCK_SRCS) $(BLOCKS_SRC)
|
||||
$$(CC_$(1)) $$(SYSTEM_CFLAGS) -static $(BINDIR)/hosted-$(1).o $(BINDIR)/v4_image_64.c $(CAPSULE_DIR_C) $$(ENGINE_SRCS) $$(SYSTEM_SRCS) $(BINDIR)/v3o-$(1)/*.o -o $$@
|
||||
$$(CC_$(1)) $$(SYSTEM_CFLAGS) -static $(BINDIR)/hosted-$(1).o $(MACHINE_64) $(CAPSULE_DIR_C) $$(ENGINE_SRCS) $$(SYSTEM_SRCS) $(BINDIR)/v3o-$(1)/*.o -o $$@
|
||||
|
||||
$(BINDIR)/boot-$(1).txt: $(BINDIR)/starforth4-$(1)
|
||||
@echo " [hosted $(1)]"
|
||||
@@ -272,7 +262,7 @@ hosted-check: $(foreach i,$(HOSTED_ISAS),$(BINDIR)/boot-$(i).txt) $(BINDIR)/star
|
||||
# in the place of system/post_cases.c): hosted-check boots it and requires
|
||||
# that the boot stops there. docs/v4.0.0/MESH.md step 6b, acceptance 4.
|
||||
$(BINDIR)/starforth4-postfail: $(BINDIR)/starforth4-amd64 $(HERE)/tests/post_cases_fail.c
|
||||
$(CC) $(SYSTEM_CFLAGS) -static $(BINDIR)/hosted-amd64.o $(BINDIR)/v4_image_64.c $(CAPSULE_DIR_C) $(ENGINE_SRCS) $(filter-out %/post_cases.c,$(SYSTEM_SRCS)) $(HERE)/tests/post_cases_fail.c $(BINDIR)/v3o-amd64/*.o -o $@
|
||||
$(CC) $(SYSTEM_CFLAGS) -static $(BINDIR)/hosted-amd64.o $(MACHINE_64) $(CAPSULE_DIR_C) $(ENGINE_SRCS) $(filter-out %/post_cases.c,$(SYSTEM_SRCS)) $(HERE)/tests/post_cases_fail.c $(BINDIR)/v3o-amd64/*.o -o $@
|
||||
|
||||
.PHONY: all test sanitize clean $(addprefix test-,$(WIDTHS))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user