feat(build): the stick and the data stick, Artemis formatted and signed at build
The stick's increment 3, Task 1 (docs/v4.0.0/plans/2026-10-27-stick-3-images.md; STICK.md 4). make boot_image TARGET=PC now writes the 2 GiB stick: ESP 64 MiB (BOOTX64.EFI, startup.nsh, starforth.cfg), StarshipOS identity 500 MiB (zeros), StarshipOS Artemis to the end. make -f kernel/Makefile ARCH=<arch> datastick writes the 1.5 GiB data stick, identity and Artemis, fresh every time. Sizes in kernel/Makefile; every partition on whole MiB. tools/mkartemis formats and signs an Artemis partition at build with the kernel's own code -- v3's block_subsystem.c (blk_subsys_confirm_format) and artemis_sig.c (artemis_sig_genesis_stamp) -- through a blkio device over a byte range of the image; --check reads one back the same way (read-only). disk_uuid from getrandom(2): each image its own. mkdiskimage.sh gains --starship, --mkartemis, --esp-mib; Milk-V and the Pi images are unchanged. The kernel is not changed. Red: scripts/check_images.sh FAIL (no datastick, the PC image one partition). Green: 23/23. Mutation: --check on a range shifted by one block fails. Accepted: suite EXIT 0; 133146, 133417, 133815, POST 538/538, dict_hash 0xfec8c47cfc6f437f; test-32, 0 failures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a4221d8b8c
commit
e177c5c6b3
+4
-1
@@ -4,9 +4,12 @@
|
||||
# any x86-64 PC whose firmware boots a UEFI removable medium. (The first to be
|
||||
# brought up on the bench is a Beelink SER5, an AMD Ryzen mini-PC -- see
|
||||
# boards/BRINGUP.md.) The monolithic loader embeds the whole kernel, so the
|
||||
# image is a GPT disk with one FAT32 EFI System Partition holding
|
||||
# image is a GPT disk whose FAT32 EFI System Partition holds
|
||||
# EFI/BOOT/BOOTX64.EFI. Write it to a USB stick with dd.
|
||||
BOARD_DESC := Generic PC (x86-64, UEFI, ACPI)
|
||||
BOARD_ARCH := amd64
|
||||
BOARD_BOOT := uefi-esp
|
||||
BOARD_IMAGE := lithos-pc.img
|
||||
# The StarshipOS stick (docs/v4.0.0/STICK.md 4): the ESP, then the StarshipOS identity and
|
||||
# Artemis partitions, Artemis formatted and signed at build. Sizes in kernel/Makefile.
|
||||
BOARD_STICK := 1
|
||||
|
||||
@@ -160,6 +160,15 @@ carrying timestamp noise in git history.
|
||||
`thumbdrives/zuse-thumb-ident.img`, which stay blank (that call is Captain
|
||||
Bob's).
|
||||
|
||||
- **The StarshipOS stick and data stick are not here** (2026-10-27,
|
||||
`docs/v4.0.0/STICK.md` §4, §9): they are build output, made fresh by
|
||||
`make boot_image TARGET=PC` (`build/boards/pc/lithos-pc.img`: ESP, StarshipOS
|
||||
identity, StarshipOS Artemis) and `make -f kernel/Makefile ARCH=<arch> datastick`
|
||||
(`build/<arch>/kernel/datastick.img`: identity and Artemis), Artemis formatted
|
||||
and signed at build by `tools/mkartemis.c`; `scripts/check_images.sh` checks
|
||||
both. The convention below is for fixtures kept as they are, not images the
|
||||
build writes every time.
|
||||
|
||||
**Convention, standing as of 2026-08-22: every virtual disk/thumb-drive image
|
||||
used for testing — Artemis persistence disks above, and USB Mass Storage
|
||||
backing images alike — lives in this directory and is a tracked, committed
|
||||
|
||||
+32
-2
@@ -180,6 +180,12 @@ MKCAPSULE_SRC = tools/mkcapsule.c tools/pkcs8_ed25519.c \
|
||||
kernel/src/crypto/scalar25519.c \
|
||||
kernel/src/crypto/sha512.c
|
||||
MKCAPSULE_BIN = $(BUILD_DIR)/tools/mkcapsule
|
||||
# mkartemis: formats and signs an Artemis partition at build with the kernel's own
|
||||
# block-subsystem and artemis_sig code (tools/mkartemis.c), built as v4/Makefile builds them.
|
||||
MKARTEMIS_SRC = tools/mkartemis.c kernel/src/artemis_sig.c \
|
||||
$(addprefix v3/src/,block_subsystem.c blkio_ram.c blkio_file.c log.c \
|
||||
platform/platform_init.c platform/linux/time.c)
|
||||
MKARTEMIS_BIN = $(BUILD_DIR)/tools/mkartemis
|
||||
# Milestone 6 (Phase 8): the snakeoil intermediate's private key, generated
|
||||
# offline outside this repo entirely (see FABRIC-2.md's Phase 8 §Milestone 6
|
||||
# writeup) -- not present in CI or a fresh checkout, so signing is skipped
|
||||
@@ -213,6 +219,17 @@ BOARD_OUT := build/boards/$(BOARD)
|
||||
endif
|
||||
BOOT_IMAGE_SIZE_MIB ?= 128
|
||||
|
||||
# The StarshipOS stick and data stick (docs/v4.0.0/STICK.md 4, "sizes: a minimum, and dynamic
|
||||
# above it"; set here and nowhere else). A board whose board.mk sets BOARD_STICK := 1 (the PC)
|
||||
# gets the stick: an ESP, the StarshipOS identity partition, and Artemis to the end, formatted
|
||||
# and signed at build. The data stick -- identity and Artemis, no ESP -- is what the `qemu`
|
||||
# targets attach with DATASTICK=1 (docs/v4.0.0/plans/2026-10-27-stick-3-images.md).
|
||||
STICK_IMAGE_MIB := 2048
|
||||
STICK_ESP_MIB := 64
|
||||
STICK_IDENT_MIB := 500
|
||||
DATASTICK_MIB := 1536
|
||||
DATASTICK_IMG = $(BUILD_DIR)/datastick.img
|
||||
|
||||
# ==============================================================================
|
||||
# TOOLCHAIN
|
||||
# ==============================================================================
|
||||
@@ -740,6 +757,17 @@ $(MKCAPSULE_BIN): $(MKCAPSULE_SRC)
|
||||
@echo "HOSTCC $(MKCAPSULE_SRC)"
|
||||
@cc -std=c99 -Wall -Wextra -O2 -Iv3/include -Ikernel/include -Itools -o $@ $(MKCAPSULE_SRC)
|
||||
|
||||
$(MKARTEMIS_BIN): $(MKARTEMIS_SRC) $(wildcard v3/include/*.h) kernel/include/starkernel/artemis_sig.h
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "HOSTCC tools/mkartemis.c"
|
||||
@cc -std=gnu99 -Wall -O2 -Iv3/include -Ikernel/include -o $@ $(MKARTEMIS_SRC)
|
||||
|
||||
# datastick -- the data stick, fresh every time it is made (STICK.md 9: "fresh for each boot").
|
||||
.PHONY: datastick
|
||||
datastick: $(MKARTEMIS_BIN)
|
||||
@bash scripts/mkdiskimage.sh --out $(DATASTICK_IMG) --table gpt --size-mib $(DATASTICK_MIB) \
|
||||
--label DATASTICK --starship $(STICK_IDENT_MIB) --mkartemis $(MKARTEMIS_BIN) --esp-mib 0
|
||||
|
||||
# Generate capsule_generated.c from capsules/
|
||||
CAPSULE_SRCS := $(shell find $(CAPSULES_DIR) -type f ! -name '.*' 2>/dev/null)
|
||||
$(CAPSULE_GENERATED): $(MKCAPSULE_BIN) $(CAPSULE_SRCS)
|
||||
@@ -1316,7 +1344,7 @@ boot_image:
|
||||
@echo " make boot_image TARGET=PC|RASPI|MILKV|ZYNQ7020"
|
||||
@exit 1
|
||||
else ifeq ($(BOARD_BOOT),uefi-esp)
|
||||
boot_image: all
|
||||
boot_image: all $(if $(BOARD_STICK),$(MKARTEMIS_BIN))
|
||||
@mkdir -p $(BOARD_OUT)
|
||||
@printf 'FS0:\\EFI\\BOOT\\%s\r\n' "$(EFI_BOOTNAME)" > $(BOARD_OUT)/startup.nsh
|
||||
@# The boot arguments, always written: system=v4 first -- v4 is the
|
||||
@@ -1324,7 +1352,9 @@ boot_image: all
|
||||
@# stick (A6); KERNEL_ARGS after it, and a later system= wins.
|
||||
@printf '%s\n' 'system=v4 $(KERNEL_ARGS)' > $(BOARD_OUT)/starforth.cfg
|
||||
@bash scripts/mkdiskimage.sh --out $(BOARD_OUT)/$(BOARD_IMAGE) --table gpt \
|
||||
--size-mib $(BOOT_IMAGE_SIZE_MIB) --label LITHOS \
|
||||
$(if $(BOARD_STICK),--size-mib $(STICK_IMAGE_MIB) --starship $(STICK_IDENT_MIB) \
|
||||
--mkartemis $(MKARTEMIS_BIN) --esp-mib $(STICK_ESP_MIB),--size-mib $(BOOT_IMAGE_SIZE_MIB)) \
|
||||
--label LITHOS \
|
||||
$(LOADER_EFI):/EFI/BOOT/$(EFI_BOOTNAME) \
|
||||
$(BOARD_OUT)/startup.nsh:/startup.nsh \
|
||||
$(BOARD_OUT)/starforth.cfg:/starforth.cfg
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
[2J[001;001H[=3h[2J[001;001H[2J[001;001H[8;042;160t[2J[001;001H[2J[001;001H[8;056;240t[2J[001;001HBdsDxe: loading Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)
|
||||
BdsDxe: starting Boot0002 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)
|
||||
[2J[001;001H[=3h[2J[001;001HStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
RAW SERIAL UP
|
||||
[CKPT 002] Serial (COM1) initialized
|
||||
Monolithic build - kernel linked directly
|
||||
Collecting boot information...
|
||||
CmdLine: parsed OK
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
GOP: linear framebuffer found
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
EBS...
|
||||
EBS OK
|
||||
Calling kernel_main (monolithic)...
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0 amd64
|
||||
Architecture: amd64
|
||||
Build: Oct 27 2026 13:31:19
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a 16550 at port 0x00000000000003f8 (COM1, probed)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 135
|
||||
Total memory: 1023 MB
|
||||
Usable memory: 966 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 248669
|
||||
Free pages : 247146
|
||||
Used pages : 1523
|
||||
Total MB : 971
|
||||
Free MB : 965
|
||||
Used MB : 5
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
APIC: IA32_APIC_BASE MSR=0x00000000fee00900
|
||||
APIC: stale-ISR drain: 0 EOI(s) issued
|
||||
APIC: initialized (xAPIC MMIO, TPR=0, SIVR=0x1FF, EOI-clear)
|
||||
APIC: init done
|
||||
|
||||
I/O APIC: init...
|
||||
I/O APIC: base=0xfec00000, gsi_base=0, overrides=5
|
||||
override: source=00 gsi=2 flags=0x0000
|
||||
override: source=05 gsi=5 flags=0x000d
|
||||
override: source=09 gsi=9 flags=0x000d
|
||||
override: source=0a gsi=10 flags=0x000d
|
||||
override: source=0b gsi=11 flags=0x000d
|
||||
i8042: keyboard ACKed enable-scanning
|
||||
i8042: IRQ1 enabled in controller config byte
|
||||
I/O APIC: keyboard IRQ1 routed (masked)
|
||||
|
||||
Timer: init...
|
||||
Timer: init start
|
||||
Timer: PM_TMR_BLK discovered from FADT at port 1544
|
||||
Timer: VM mode detected (hypervisor present).
|
||||
Timer: HPET calibration disabled (VM-exit MMIO would poison timing).
|
||||
Timer: WARNING: invariant TSC not present under hypervisor.
|
||||
Timer: continuing in RELATIVE mode (no determinism guarantees).
|
||||
Timer: RDTSCP not present; using RDTSC (less serialized).
|
||||
Timer: CPUID frequency unavailable; trying PM Timer...
|
||||
Timer: trust=1 (0=NONE,1=REL,2=ABS), TSC=2102367869 Hz
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 536870872
|
||||
Free bytes: 536870872
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 24641536
|
||||
Heap end addr: 561512448
|
||||
|
||||
Heartbeat: init...
|
||||
APIC Timer: calibrating...
|
||||
APIC Timer: apic_hz=1012154133, tick_hz=100, initial_count=10121541
|
||||
APIC Timer: configured (masked, ready to start)
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
System: StarForth v4 (this build's default)
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:sys:map-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:map-64.f18 capsule_hash=0x949eb6a1e9260e49
|
||||
V4: capsule v4:sys:core.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:core.f18 capsule_hash=0xb8f167892ec18c28
|
||||
V4: capsule v4:sys:input.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:input.f18 capsule_hash=0x85d3ec486d929a79
|
||||
V4: capsule v4:sys:dict.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:dict.f18 capsule_hash=0x1379bd3b5de811dc
|
||||
V4: capsule v4:sys:codegen.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:codegen.f18 capsule_hash=0x36d2ae84d2911b90
|
||||
V4: capsule v4:sys:compile.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:compile.f18 capsule_hash=0x11145c4c2ab819d8
|
||||
V4: capsule v4:sys:quit.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:quit.f18 capsule_hash=0x43cadf3b21ddbf3e
|
||||
V4: capsule v4:sys:forth.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:forth.f18 capsule_hash=0x16cab4a1268b85da
|
||||
V4: capsule v4:sys:numout.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:numout.f18 capsule_hash=0x85a240ad3fb2b299
|
||||
V4: capsule v4:sys:words.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:words.f18 capsule_hash=0xb1d381f927d9f14e
|
||||
V4: capsule v4:sys:system.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:system.f18 capsule_hash=0xd92203664c2915bd
|
||||
V4: capsule v4:sys:qmath.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:qmath.f18 capsule_hash=0xdb4140713dd857f3
|
||||
V4: capsule v4:sys:blocks.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:blocks.f18 capsule_hash=0x76307ef48678dc2a
|
||||
V4: capsule v4:sys:log.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:log.f18 capsule_hash=0xfc6540e6b824a52b
|
||||
V4: capsule v4:sys:acl.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:acl.f18 capsule_hash=0x6845aa048db7eb22
|
||||
V4: capsule v4:sys:end.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:end.f18 capsule_hash=0x5ef01312c07b79cc
|
||||
PARITY:V4_ROM words=2372 rom_hash=0x87b23d3ae2643c8d instructions=59145258
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0x033e1c05c09a1df8
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0xfec8c47cfc6f437f
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
PCI: init...
|
||||
PCI: ECAM mapped (amd64)
|
||||
virtio-blk: found device
|
||||
Artemis: virtio-blk attached
|
||||
virtio-input: no device on PCI bus 0
|
||||
Starting heartbeat...
|
||||
APIC Timer: started (LVT=0x00020020 ICR=10121541)
|
||||
I/O APIC: keyboard IRQ1 unmasked
|
||||
Heartbeat running.
|
||||
blkio_usb: MSC device ready
|
||||
[38;2;255;165;0m[Hera][39m Zuse: identity confirmed from attached thumbdrive
|
||||
[38;2;255;165;0m[zuse@Hera][39m [38;2;85;255;255mok> [39m3 4 + .
|
||||
[38;2;255;165;0m[zuse@Hera][39m 7 ok
|
||||
[38;2;255;165;0m[zuse@Hera][39m [38;2;85;255;255mok> [39m
|
||||
@@ -0,0 +1,130 @@
|
||||
UEFI firmware (version 2025.11-3ubuntu7.3 built at 15:40:26 on Sep 23 2026)
|
||||
[2J[001;001H[=3h[2J[001;001H[2J[001;001H[8;031;100t[2J[001;001HBdsDxe: failed to load Boot0002 "UEFI Misc Device" from PciRoot(0x0)/Pci(0x2,0x0): Not Found
|
||||
BdsDxe: failed to load Boot0003 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:04.0-1" from PciRoot(0x0)/Pci(0x4,0x0)/USB(0x0,0x0): Not Found
|
||||
BdsDxe: loading Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0)
|
||||
BdsDxe: starting Boot0004 "UEFI Misc Device 2" from PciRoot(0x0)/Pci(0x6,0x0)
|
||||
[2J[001;001H[=3h[2J[001;001HStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
Collecting boot information...
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0 aarch64
|
||||
Architecture: aarch64
|
||||
Build: Oct 27 2026 13:33:50
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a PL011 at 0x0000000009000000 (no devicetree: QEMU's)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 108
|
||||
Total memory: 4093 MB
|
||||
Usable memory: 4054 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 1039275
|
||||
Free pages : 1037864
|
||||
Used pages : 1411
|
||||
Total MB : 4059
|
||||
Free MB : 4054
|
||||
Used MB : 5
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
AArch64: running at EL1
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
PSCI: no DTB -- using HVC (QEMU virt-machine default)
|
||||
GICv2: no DTB GIC node -- using QEMU virt-machine defaults
|
||||
GICv2: distributor+CPU interface enabled, PPI 30
|
||||
APIC: init done
|
||||
|
||||
Timer: init...
|
||||
Timer: AArch64 generic timer initialised.
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 2147483608
|
||||
Free bytes: 2147483608
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 1207959552
|
||||
Heap end addr: 3355443200
|
||||
|
||||
Heartbeat: init...
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
System: StarForth v4 (this build's default)
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:sys:map-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:map-64.f18 capsule_hash=0x949eb6a1e9260e49
|
||||
V4: capsule v4:sys:core.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:core.f18 capsule_hash=0xb8f167892ec18c28
|
||||
V4: capsule v4:sys:input.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:input.f18 capsule_hash=0x85d3ec486d929a79
|
||||
V4: capsule v4:sys:dict.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:dict.f18 capsule_hash=0x1379bd3b5de811dc
|
||||
V4: capsule v4:sys:codegen.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:codegen.f18 capsule_hash=0x36d2ae84d2911b90
|
||||
V4: capsule v4:sys:compile.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:compile.f18 capsule_hash=0x11145c4c2ab819d8
|
||||
V4: capsule v4:sys:quit.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:quit.f18 capsule_hash=0x43cadf3b21ddbf3e
|
||||
V4: capsule v4:sys:forth.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:forth.f18 capsule_hash=0x16cab4a1268b85da
|
||||
V4: capsule v4:sys:numout.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:numout.f18 capsule_hash=0x85a240ad3fb2b299
|
||||
V4: capsule v4:sys:words.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:words.f18 capsule_hash=0xb1d381f927d9f14e
|
||||
V4: capsule v4:sys:system.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:system.f18 capsule_hash=0xd92203664c2915bd
|
||||
V4: capsule v4:sys:qmath.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:qmath.f18 capsule_hash=0xdb4140713dd857f3
|
||||
V4: capsule v4:sys:blocks.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:blocks.f18 capsule_hash=0x76307ef48678dc2a
|
||||
V4: capsule v4:sys:log.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:log.f18 capsule_hash=0xfc6540e6b824a52b
|
||||
V4: capsule v4:sys:acl.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:acl.f18 capsule_hash=0x6845aa048db7eb22
|
||||
V4: capsule v4:sys:end.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:end.f18 capsule_hash=0x5ef01312c07b79cc
|
||||
PARITY:V4_ROM words=2372 rom_hash=0x87b23d3ae2643c8d instructions=59145258
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0x033e1c05c09a1df8
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0xfec8c47cfc6f437f
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
Artemis: virtio-blk attached
|
||||
virtio-input: found device
|
||||
virtio-input: driver ready
|
||||
Starting heartbeat...
|
||||
Heartbeat running.
|
||||
blkio_usb: MSC device ready
|
||||
[38;2;255;165;0m[Hera][39m Zuse: identity confirmed from attached thumbdrive
|
||||
[38;2;255;165;0m[zuse@Hera][39m [38;2;85;255;255mok> [39m3 4 + .
|
||||
[38;2;255;165;0m[zuse@Hera][39m 7 ok
|
||||
[38;2;255;165;0m[zuse@Hera][39m [38;2;85;255;255mok> [39m
|
||||
@@ -0,0 +1,201 @@
|
||||
|
||||
OpenSBI v1.8
|
||||
____ _____ ____ _____
|
||||
/ __ \ / ____| _ \_ _|
|
||||
| | | |_ __ ___ _ __ | (___ | |_) || |
|
||||
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
|
||||
| |__| | |_) | __/ | | |____) | |_) || |_
|
||||
\____/| .__/ \___|_| |_|_____/|____/_____|
|
||||
| |
|
||||
|_|
|
||||
|
||||
Platform Name : riscv-virtio,qemu
|
||||
Platform Features : medeleg
|
||||
Platform HART Count : 1
|
||||
Platform HART Protection : pmp
|
||||
Platform IPI Device : aclint-mswi
|
||||
Platform Timer Device : aclint-mtimer @ 10000000Hz
|
||||
Platform Console Device : uart8250
|
||||
Platform HSM Device : ---
|
||||
Platform PMU Device : ---
|
||||
Platform Reboot Device : syscon-reboot
|
||||
Platform Shutdown Device : syscon-poweroff
|
||||
Platform Suspend Device : ---
|
||||
Platform CPPC Device : ---
|
||||
Firmware Base : 0x80000000
|
||||
Firmware Size : 321 KB
|
||||
Firmware RW Offset : 0x40000
|
||||
Firmware RW Size : 65 KB
|
||||
Firmware Heap Offset : 0x47000
|
||||
Firmware Heap Size : 37 KB (total), 0 KB (reserved), 12 KB (used), 23 KB (free)
|
||||
Firmware Scratch Size : 4096 B (total), 1464 B (used), 2632 B (free)
|
||||
Runtime SBI Version : 3.0
|
||||
Standard SBI Extensions : ipi,pmu,srst,sse,hsm,rfnc,fwft,time,base,legacy,dbcn,dbtr
|
||||
Experimental SBI Extensions : none
|
||||
|
||||
Domain0 Name : root
|
||||
Domain0 Boot HART : 0
|
||||
Domain0 HARTs : 0*
|
||||
Domain0 Region00 : 0x0000000080040000-0x000000008005ffff M: (F,R,W) S/U: ()
|
||||
Domain0 Region01 : 0x0000000080000000-0x000000008003ffff M: (F,R,X) S/U: ()
|
||||
Domain0 Region02 : 0x0000000000100000-0x0000000000100fff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region03 : 0x0000000010000000-0x0000000010000fff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region04 : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: ()
|
||||
Domain0 Region05 : 0x000000000c400000-0x000000000c5fffff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region06 : 0x000000000c000000-0x000000000c3fffff M: (I,R,W) S/U: (R,W)
|
||||
Domain0 Region07 : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)
|
||||
Domain0 Next Address : 0x0000000020000000
|
||||
Domain0 Next Arg1 : 0x00000000bfe00000
|
||||
Domain0 Next Mode : S-mode
|
||||
Domain0 SysReset : yes
|
||||
Domain0 SysSuspend : yes
|
||||
|
||||
Boot HART ID : 0
|
||||
Boot HART Domain : root
|
||||
Boot HART Priv Version : v1.12
|
||||
Boot HART Base ISA : rv64imafdch
|
||||
Boot HART ISA Extensions : sstc,zicntr,zihpm,zicboz,zicbom,sdtrig,svadu
|
||||
Boot HART PMP Count : 16
|
||||
Boot HART PMP Granularity : 2 bits
|
||||
Boot HART PMP Address Bits : 54
|
||||
Boot HART MHPM Info : 16 (0x0007fff8)
|
||||
Boot HART Debug Triggers : 2 triggers
|
||||
Boot HART MIDELEG : 0x0000000000001666
|
||||
Boot HART MEDELEG : 0x0000000000f4b509
|
||||
[2J[004D[=3h[2J[009D[2J[004D[8;031;100t[2J[016DRISC-V EDK2 firmware version 2025.11-3ubuntu7.3
|
||||
Press ESCAPE within 5 seconds for boot options ERROR: C40000002:V03051002 I0 6D33944A-EC75-4855-A54D-809C75241F6C 83FFF850
|
||||
BdsDxe: failed to load Boot0001 "UEFI Misc Device" fr
|
||||
om PciRoot(0x0)/Pci(0x1,0x0): Not Found
|
||||
[2J[001;001H[=3h[2J[009DStarKernel UEFI Loader
|
||||
Loading kernel from ESP...
|
||||
[CKPT 001] Entered efi_main - ConOut live
|
||||
Monolithic build - kernel linked directly
|
||||
Collecting boot information...
|
||||
CmdLine: parsed OK
|
||||
[CKPT 004] Command line parsed
|
||||
[CKPT 005] Kernel stack allocation decided
|
||||
[CKPT 006] Boot info collected (ACPI table located)
|
||||
GOP: linear framebuffer found
|
||||
[CKPT 007] GOP: linear framebuffer found
|
||||
[CKPT 008] About to enter ExitBootServices retry loop
|
||||
Calling kernel_main (monolithic)...
|
||||
riscv64 item 4.3.5a: satp state at kernel entry (before switch)
|
||||
satp.MODE = 0x000000000000000a
|
||||
satp.PPN = 0x00000000000bf868
|
||||
__kernel_start = 0x00000000bdc21efa
|
||||
riscv64: satp cleared -- Bare mode, explicit (item 4.3.5a)
|
||||
|
||||
|
||||
_____ _ _ __ _
|
||||
/ ____| | | |/ / | |
|
||||
| (___ | |_ __ _ _ __| ' / ___ _ __ _ __ ___| |
|
||||
\___ \| __/ _` | '__| < / _ \ '__| '_ \ / _ \ |
|
||||
____) | || (_| | | | . \ __/ | | | | | __/ |
|
||||
|_____/ \__\__,_|_| |_|\_\___|_| |_| |_|\___|_|
|
||||
|
||||
LithosAnanke v2.1.0 riscv64
|
||||
Architecture: riscv64
|
||||
Build: Oct 27 2026 13:37:35
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a 16550 at 0x0000000010000000 (no devicetree: QEMU's)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 98
|
||||
Total memory: 1020 MB
|
||||
Usable memory: 974 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 250196
|
||||
Free pages : 249544
|
||||
Used pages : 652
|
||||
Total MB : 977
|
||||
Free MB : 974
|
||||
Used MB : 2
|
||||
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM initialized (mapped RAM, CR3 switched)
|
||||
VMM self-test: mapped OK at 0xffff800000000000
|
||||
VMM self-test complete.
|
||||
|
||||
IDT installed.
|
||||
|
||||
APIC: init...
|
||||
PLIC: no DTB PLIC node -- using QEMU virt-machine default (base=0x0c000000)
|
||||
PLIC: init (S-mode context 1, threshold=0)
|
||||
APIC: init done
|
||||
|
||||
Timer: init...
|
||||
Timer: RISC-V time CSR @ 10000000 Hz (FALLBACK, no devicetree)
|
||||
Timer: init done
|
||||
|
||||
Kernel heap initialized.
|
||||
Heap statistics:
|
||||
Total bytes: 536870872
|
||||
Free bytes: 536870872
|
||||
Used bytes: 0
|
||||
Peak bytes: 0
|
||||
Heap base addr: 2214588416
|
||||
Heap end addr: 2751459328
|
||||
|
||||
Heartbeat: init...
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
System: StarForth v4 (this build's default)
|
||||
StarForth v4: one host node, the F18-derived engine
|
||||
V4: capsule v4:sys:map-64.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:map-64.f18 capsule_hash=0x949eb6a1e9260e49
|
||||
V4: capsule v4:sys:core.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:core.f18 capsule_hash=0xb8f167892ec18c28
|
||||
V4: capsule v4:sys:input.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:input.f18 capsule_hash=0x85d3ec486d929a79
|
||||
V4: capsule v4:sys:dict.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:dict.f18 capsule_hash=0x1379bd3b5de811dc
|
||||
V4: capsule v4:sys:codegen.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:codegen.f18 capsule_hash=0x36d2ae84d2911b90
|
||||
V4: capsule v4:sys:compile.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:compile.f18 capsule_hash=0x11145c4c2ab819d8
|
||||
V4: capsule v4:sys:quit.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:quit.f18 capsule_hash=0x43cadf3b21ddbf3e
|
||||
V4: capsule v4:sys:forth.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:forth.f18 capsule_hash=0x16cab4a1268b85da
|
||||
V4: capsule v4:sys:numout.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:numout.f18 capsule_hash=0x85a240ad3fb2b299
|
||||
V4: capsule v4:sys:words.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:words.f18 capsule_hash=0xb1d381f927d9f14e
|
||||
V4: capsule v4:sys:system.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:system.f18 capsule_hash=0xd92203664c2915bd
|
||||
V4: capsule v4:sys:qmath.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:qmath.f18 capsule_hash=0xdb4140713dd857f3
|
||||
V4: capsule v4:sys:blocks.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:blocks.f18 capsule_hash=0x76307ef48678dc2a
|
||||
V4: capsule v4:sys:log.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:log.f18 capsule_hash=0xfc6540e6b824a52b
|
||||
V4: capsule v4:sys:acl.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:acl.f18 capsule_hash=0x6845aa048db7eb22
|
||||
V4: capsule v4:sys:end.f18 signature: missing (unsigned)
|
||||
PARITY:V4_F18 name=v4:sys:end.f18 capsule_hash=0x5ef01312c07b79cc
|
||||
PARITY:V4_ROM words=2372 rom_hash=0x87b23d3ae2643c8d instructions=59145258
|
||||
V4: capsule v4:forth79.4th signature: missing (unsigned)
|
||||
PARITY:V4_CAPSULE name=v4:forth79.4th capsule_id=0x4055641ee17d176b capsule_hash=0x4055641ee17d176b dict_hash=0x033e1c05c09a1df8
|
||||
PARITY:V4_POST tests=538 pass=538 fail=0
|
||||
PARITY:V4_SYSTEM word_count=317 dict_hash=0xfec8c47cfc6f437f
|
||||
PARITY:OK
|
||||
POST: PASSED
|
||||
PCI: init...
|
||||
virtio-blk: found device
|
||||
Artemis: virtio-blk attached
|
||||
virtio-input: found device
|
||||
virtio-input: driver ready
|
||||
Starting heartbeat...
|
||||
SBI: timer armed (TIME extension)
|
||||
Heartbeat running.
|
||||
blkio_usb: MSC device ready
|
||||
[38;2;255;165;0m[Hera][39m Zuse: identity confirmed from attached thumbdrive
|
||||
[38;2;255;165;0m[zuse@Hera][39m [38;2;85;255;255mok> [39m3 4 + .
|
||||
[38;2;255;165;0m[zuse@Hera][39m 7 ok
|
||||
[38;2;255;165;0m[zuse@Hera][39m [38;2;85;255;255mok> [39m
|
||||
Executable
+103
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env bash
|
||||
# check_images.sh -- build the stick and the data stick and check them
|
||||
# (docs/v4.0.0/plans/2026-10-27-stick-3-images.md, Task 1; docs/v4.0.0/STICK.md 4).
|
||||
#
|
||||
# The stick: make boot_image TARGET=PC -> build/boards/pc/lithos-pc.img
|
||||
# The data stick: make -f kernel/Makefile ARCH=amd64 datastick -> build/amd64/kernel/datastick.img
|
||||
#
|
||||
# Prints PASS:/FAIL: per check and RESULT:; exits 0 only if every check passes.
|
||||
set -uo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
PATH="$PATH:/usr/sbin:/sbin"
|
||||
|
||||
STICK=build/boards/pc/lithos-pc.img
|
||||
DATA=build/amd64/kernel/datastick.img
|
||||
MKARTEMIS=build/amd64/kernel/tools/mkartemis
|
||||
ESP_T=C12A7328-F81F-11D2-BA4B-00A0C93EC93B
|
||||
IDENT_T=23BEBFE1-4817-4CF3-A537-9069BF159788
|
||||
ART_T=BCD7B586-1C8E-4EEF-86A3-273A8D8EE624
|
||||
ok=1
|
||||
|
||||
check() { # check "what" command...
|
||||
local what="$1"; shift
|
||||
if "$@" >/dev/null 2>&1; then echo "PASS: $what"; else echo "FAIL: $what"; ok=0; fi
|
||||
}
|
||||
|
||||
# part IMG N FIELD -- a field (start, size, type) of partition N (1-based) from sfdisk --json
|
||||
part() {
|
||||
sfdisk --json "$1" 2>/dev/null | python3 -c "
|
||||
import json, sys
|
||||
p = json.load(sys.stdin)['partitiontable']
|
||||
parts = p['partitions']
|
||||
n = int(sys.argv[1])
|
||||
if sys.argv[2] == 'count': print(len(parts))
|
||||
elif sys.argv[2] == 'lastlba': print(p['lastlba'])
|
||||
elif n <= len(parts): print(str(parts[n - 1][sys.argv[2]]).upper())
|
||||
" "$2" "$3" 2>/dev/null
|
||||
}
|
||||
|
||||
eq() { [ "$1" = "$2" ]; }
|
||||
|
||||
# geometry IMG -- every partition starts and ends on a whole MiB, the last one within a MiB of
|
||||
# the last usable LBA, and each starts where the one before it ends
|
||||
geometry() {
|
||||
local img="$1" n i prev=2048 s z last
|
||||
n=$(part "$img" 0 count); last=$(part "$img" 0 lastlba)
|
||||
for i in $(seq 1 "$n"); do
|
||||
s=$(part "$img" "$i" start); z=$(part "$img" "$i" size)
|
||||
[ "$s" = "$prev" ] && [ $((s % 2048)) -eq 0 ] && [ $((z % 2048)) -eq 0 ] || return 1
|
||||
prev=$((s + z))
|
||||
done
|
||||
[ $((prev - 1)) -le "$last" ] && [ $((last - (prev - 1))) -lt 2048 ]
|
||||
}
|
||||
|
||||
zeros() { # zeros IMG N -- partition N is all zeros
|
||||
local s z
|
||||
s=$(part "$1" "$2" start); z=$(part "$1" "$2" size)
|
||||
[ -n "$s" ] && [ -n "$z" ] && cmp -s -i "$((s * 512)):0" -n "$((z * 512))" "$1" /dev/zero
|
||||
}
|
||||
|
||||
artemis_check() { # artemis_check IMG N -- mkartemis --check on partition N
|
||||
"$MKARTEMIS" --check "$1" --first-lba "$(part "$1" "$2" start)" --sectors "$(part "$1" "$2" size)"
|
||||
}
|
||||
|
||||
uuid() { artemis_check "$1" "$2" 2>/dev/null | sed -n 's/.*disk_uuid \([0-9a-f]*\).*/\1/p'; }
|
||||
|
||||
echo "== building"
|
||||
make boot_image TARGET=PC >/dev/null 2>&1; echo "boot_image exit $?"
|
||||
make -f kernel/Makefile ARCH=amd64 datastick >/dev/null 2>&1; echo "datastick exit $?"
|
||||
|
||||
echo "== the stick ($STICK)"
|
||||
check "it exists, 2048 MiB" eq "$(stat -c %s "$STICK" 2>/dev/null)" "$((2048 * 1048576))"
|
||||
check "three partitions" eq "$(part "$STICK" 0 count)" 3
|
||||
check "1: EFI System, 64 MiB at LBA 2048" eq "$(part "$STICK" 1 type)/$(part "$STICK" 1 start)/$(part "$STICK" 1 size)" "$ESP_T/2048/131072"
|
||||
check "2: StarshipOS identity, 500 MiB" eq "$(part "$STICK" 2 type)/$(part "$STICK" 2 start)/$(part "$STICK" 2 size)" "$IDENT_T/133120/1024000"
|
||||
check "3: StarshipOS Artemis, the rest" eq "$(part "$STICK" 3 type)/$(part "$STICK" 3 start)" "$ART_T/1157120"
|
||||
check "whole MiB, contiguous, Artemis to the end" geometry "$STICK"
|
||||
check "sfdisk --verify: the GPT is clean" sfdisk --verify "$STICK"
|
||||
OFF=$((2048 * 512))
|
||||
check "the ESP holds EFI/BOOT/BOOTX64.EFI" mdir -i "$STICK@@$OFF" ::/EFI/BOOT/BOOTX64.EFI
|
||||
check "the ESP holds startup.nsh" mdir -i "$STICK@@$OFF" ::/startup.nsh
|
||||
check "starforth.cfg's first word is system=v4" eq "$(mtype -i "$STICK@@$OFF" ::/starforth.cfg 2>/dev/null | awk '{print $1; exit}')" "system=v4"
|
||||
check "the identity partition is all zeros" zeros "$STICK" 2
|
||||
check "Artemis: STFR v2, signature ok" artemis_check "$STICK" 3
|
||||
|
||||
echo "== the data stick ($DATA)"
|
||||
check "it exists, 1536 MiB" eq "$(stat -c %s "$DATA" 2>/dev/null)" "$((1536 * 1048576))"
|
||||
check "two partitions" eq "$(part "$DATA" 0 count)" 2
|
||||
check "1: StarshipOS identity, 500 MiB at LBA 2048" eq "$(part "$DATA" 1 type)/$(part "$DATA" 1 start)/$(part "$DATA" 1 size)" "$IDENT_T/2048/1024000"
|
||||
check "2: StarshipOS Artemis, the rest" eq "$(part "$DATA" 2 type)/$(part "$DATA" 2 start)" "$ART_T/1026048"
|
||||
check "whole MiB, contiguous, Artemis to the end" geometry "$DATA"
|
||||
check "sfdisk --verify: the GPT is clean" sfdisk --verify "$DATA"
|
||||
check "the identity partition is all zeros" zeros "$DATA" 1
|
||||
check "Artemis: STFR v2, signature ok" artemis_check "$DATA" 2
|
||||
U1=$(uuid "$DATA" 2)
|
||||
make -f kernel/Makefile ARCH=amd64 datastick >/dev/null 2>&1
|
||||
U2=$(uuid "$DATA" 2)
|
||||
check "made again, it is fresh: its own disk_uuid ($U1 / $U2)" test -n "$U1" -a -n "$U2" -a "$U1" != "$U2"
|
||||
|
||||
# the builds regenerate these; put them back as committed (as qemu_session.py does)
|
||||
git checkout -q -- v3/include/version.h capsules/BLOCK_MAP.md sbom.spdx sbom.spdx.json
|
||||
|
||||
echo "RESULT: $([ $ok = 1 ] && echo PASS || echo FAIL)"
|
||||
[ $ok = 1 ]
|
||||
+48
-4
@@ -15,6 +15,14 @@
|
||||
# SRC:DEST [SRC:DEST ...]
|
||||
#
|
||||
# --table gpt -> partition type "EFI System" (UEFI firmware, U-Boot bootefi)
|
||||
#
|
||||
# The StarshipOS stick and data stick (docs/v4.0.0/STICK.md 4; --table gpt only):
|
||||
# --starship IDENT_MIB --mkartemis TOOL --esp-mib E
|
||||
# lays out an ESP of E MiB holding the SRC:DEST files (E=0: no ESP, no files),
|
||||
# then a StarshipOS identity partition of IDENT_MIB MiB (all zeros), then a
|
||||
# StarshipOS Artemis partition to the last whole MiB before the backup GPT,
|
||||
# formatted and signed by TOOL (tools/mkartemis.c). Every partition starts and
|
||||
# ends on a whole MiB, so on 1 KiB blocks, as the kernel's GPT reader needs.
|
||||
# --table mbr -> partition type 0x0c FAT32 (LBA) (Raspberry Pi firmware)
|
||||
# DEST is an absolute path inside the FAT filesystem; parent directories are
|
||||
# created as needed.
|
||||
@@ -23,13 +31,16 @@
|
||||
# root, no loop devices.
|
||||
set -euo pipefail
|
||||
|
||||
OUT="" TABLE="" SIZE_MIB="" LABEL=""
|
||||
OUT="" TABLE="" SIZE_MIB="" LABEL="" IDENT_MIB="" MKARTEMIS="" ESP_MIB=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--out) OUT="$2"; shift 2 ;;
|
||||
--table) TABLE="$2"; shift 2 ;;
|
||||
--size-mib) SIZE_MIB="$2"; shift 2 ;;
|
||||
--label) LABEL="$2"; shift 2 ;;
|
||||
--starship) IDENT_MIB="$2"; shift 2 ;;
|
||||
--mkartemis) MKARTEMIS="$2"; shift 2 ;;
|
||||
--esp-mib) ESP_MIB="$2"; shift 2 ;;
|
||||
--) shift; break ;;
|
||||
-*) echo "mkdiskimage.sh: unknown option $1" >&2; exit 2 ;;
|
||||
*) break ;;
|
||||
@@ -38,7 +49,12 @@ done
|
||||
|
||||
[ -n "$OUT" ] && [ -n "$TABLE" ] && [ -n "$SIZE_MIB" ] && [ -n "$LABEL" ] || {
|
||||
echo "mkdiskimage.sh: --out, --table, --size-mib and --label are required" >&2; exit 2; }
|
||||
[ $# -gt 0 ] || { echo "mkdiskimage.sh: no SRC:DEST files given" >&2; exit 2; }
|
||||
if [ -n "$IDENT_MIB" ]; then
|
||||
[ "$TABLE" = gpt ] && [ -n "$MKARTEMIS" ] && [ -n "$ESP_MIB" ] || {
|
||||
echo "mkdiskimage.sh: --starship needs --table gpt, --mkartemis and --esp-mib" >&2; exit 2; }
|
||||
[ "$ESP_MIB" -gt 0 ] || [ $# -eq 0 ] || { echo "mkdiskimage.sh: --esp-mib 0 takes no files" >&2; exit 2; }
|
||||
fi
|
||||
[ $# -gt 0 ] || [ "${ESP_MIB:-}" = 0 ] || { echo "mkdiskimage.sh: no SRC:DEST files given" >&2; exit 2; }
|
||||
|
||||
for tool in sfdisk mkfs.fat mmd mcopy; do
|
||||
command -v "$tool" >/dev/null 2>&1 || PATH="$PATH:/usr/sbin:/sbin"
|
||||
@@ -54,13 +70,37 @@ case "$TABLE" in
|
||||
*) echo "mkdiskimage.sh: --table must be gpt or mbr" >&2; exit 2 ;;
|
||||
esac
|
||||
PART_SECTORS=$(( LAST - START + 1 ))
|
||||
# StarshipOS partition types (kernel/src/gpt.c)
|
||||
IDENT_TYPE="23BEBFE1-4817-4CF3-A537-9069BF159788"
|
||||
ART_TYPE="BCD7B586-1C8E-4EEF-86A3-273A8D8EE624"
|
||||
if [ -n "$IDENT_MIB" ]; then
|
||||
PART_SECTORS=$(( ESP_MIB * 2048 ))
|
||||
IDENT_START=$(( START + PART_SECTORS ))
|
||||
IDENT_SECTORS=$(( IDENT_MIB * 2048 ))
|
||||
ART_START=$(( IDENT_START + IDENT_SECTORS ))
|
||||
ART_SECTORS=$(( (LAST + 1 - ART_START) / 2048 * 2048 ))
|
||||
[ "$ART_SECTORS" -gt 0 ] || { echo "mkdiskimage.sh: no room for Artemis in ${SIZE_MIB} MiB" >&2; exit 2; }
|
||||
fi
|
||||
|
||||
ESP="$OUT.part1"
|
||||
rm -f "$OUT" "$ESP"
|
||||
mkdir -p "$(dirname "$OUT")"
|
||||
|
||||
truncate -s $(( TOTAL_SECTORS * 512 )) "$OUT"
|
||||
if [ "$TABLE" = gpt ]; then
|
||||
if [ -n "$IDENT_MIB" ]; then
|
||||
{
|
||||
echo "label: gpt"
|
||||
[ "$ESP_MIB" -gt 0 ] && printf 'start=%d, size=%d, type=%s, name="EFI System"\n' "$START" "$PART_SECTORS" "$PTYPE"
|
||||
printf 'start=%d, size=%d, type=%s, name="StarshipOS identity"\n' "$IDENT_START" "$IDENT_SECTORS" "$IDENT_TYPE"
|
||||
printf 'start=%d, size=%d, type=%s, name="StarshipOS Artemis"\n' "$ART_START" "$ART_SECTORS" "$ART_TYPE"
|
||||
} | sfdisk --quiet "$OUT"
|
||||
"$MKARTEMIS" --format "$OUT" --first-lba "$ART_START" --sectors "$ART_SECTORS" >/dev/null || {
|
||||
echo "mkdiskimage.sh: formatting Artemis failed" >&2; rm -f "$OUT"; exit 1; }
|
||||
if [ "$ESP_MIB" = 0 ]; then
|
||||
echo " IMAGE $OUT (gpt, ${SIZE_MIB} MiB: StarshipOS identity ${IDENT_MIB} MiB, Artemis $(( ART_SECTORS / 2048 )) MiB)"
|
||||
exit 0
|
||||
fi
|
||||
elif [ "$TABLE" = gpt ]; then
|
||||
printf 'label: gpt\nstart=%d, size=%d, type=%s, name="EFI System"\n' \
|
||||
"$START" "$PART_SECTORS" "$PTYPE" | sfdisk --quiet "$OUT"
|
||||
else
|
||||
@@ -88,4 +128,8 @@ done
|
||||
|
||||
dd if="$ESP" of="$OUT" bs=512 seek="$START" conv=notrunc status=none
|
||||
rm -f "$ESP"
|
||||
echo " IMAGE $OUT ($TABLE, ${SIZE_MIB} MiB, FAT32 '$LABEL')"
|
||||
if [ -n "$IDENT_MIB" ]; then
|
||||
echo " IMAGE $OUT (gpt, ${SIZE_MIB} MiB: ESP ${ESP_MIB} MiB FAT32 '$LABEL', StarshipOS identity ${IDENT_MIB} MiB, Artemis $(( ART_SECTORS / 2048 )) MiB)"
|
||||
else
|
||||
echo " IMAGE $OUT ($TABLE, ${SIZE_MIB} MiB, FAT32 '$LABEL')"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/* mkartemis.c -- format, or check, an Artemis partition inside a disk image.
|
||||
*
|
||||
* The stick's Artemis partition is formatted when the image is built, not on
|
||||
* first boot (docs/v4.0.0/STICK.md 4): its STFR v2 volume header, BAM and
|
||||
* relocation table, and its artemis_sig_t genesis signature. This tool does
|
||||
* it with the kernel's own code -- v3's block_subsystem.c
|
||||
* (blk_subsys_confirm_format) and kernel/src/artemis_sig.c
|
||||
* (artemis_sig_genesis_stamp, artemis_sig_check) -- through a blkio device
|
||||
* over a byte range of the image file, so the bytes are exactly those the
|
||||
* kernel writes. Zuse's genesis marker is not written: the first boot does
|
||||
* that. docs/v4.0.0/plans/2026-10-27-stick-3-images.md.
|
||||
*
|
||||
* mkartemis --format IMG --first-lba L --sectors N
|
||||
* mkartemis --check IMG --first-lba L --sectors N
|
||||
*
|
||||
* L and N count 512-byte sectors; both must be even (1 KiB blocks).
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/random.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "blkio.h"
|
||||
#include "block_subsystem.h"
|
||||
#include "starkernel/artemis_sig.h"
|
||||
#include "starkernel/rng.h"
|
||||
|
||||
/* The kernel draws disk_uuid from its entropy backend; on the build machine
|
||||
* that is the host's own, getrandom(2). */
|
||||
int rng_get_bytes(uint8_t *buf, size_t n)
|
||||
{
|
||||
while (n > 0) {
|
||||
ssize_t got = getrandom(buf, n, 0);
|
||||
if (got < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
return -1;
|
||||
}
|
||||
buf += got;
|
||||
n -= (size_t)got;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---- a blkio device over [first_lba, first_lba + sectors) of a file ---- */
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
off_t base; /* first_lba * 512 */
|
||||
uint32_t blocks; /* sectors / 2 */
|
||||
int read_only;
|
||||
} range_t;
|
||||
|
||||
static int range_open(blkio_dev_t *dev, const blkio_params_t *p)
|
||||
{
|
||||
range_t *r = (range_t *)p->opaque;
|
||||
dev->state = r;
|
||||
dev->forth_block_size = BLKIO_FORTH_BLOCK_SIZE;
|
||||
dev->total_blocks = r->blocks;
|
||||
return BLKIO_OK;
|
||||
}
|
||||
|
||||
static int range_close(blkio_dev_t *dev) { (void)dev; return BLKIO_OK; }
|
||||
|
||||
static int range_read(blkio_dev_t *dev, uint32_t fblock, void *dst)
|
||||
{
|
||||
range_t *r = (range_t *)dev->state;
|
||||
if (fblock >= r->blocks) return BLKIO_EINVAL;
|
||||
if (pread(r->fd, dst, BLKIO_FORTH_BLOCK_SIZE, r->base + (off_t)fblock * BLKIO_FORTH_BLOCK_SIZE)
|
||||
!= (ssize_t)BLKIO_FORTH_BLOCK_SIZE) return BLKIO_EIO;
|
||||
return BLKIO_OK;
|
||||
}
|
||||
|
||||
static int range_write(blkio_dev_t *dev, uint32_t fblock, const void *src)
|
||||
{
|
||||
range_t *r = (range_t *)dev->state;
|
||||
if (fblock >= r->blocks) return BLKIO_EINVAL;
|
||||
if (r->read_only) return BLKIO_EIO;
|
||||
if (pwrite(r->fd, src, BLKIO_FORTH_BLOCK_SIZE, r->base + (off_t)fblock * BLKIO_FORTH_BLOCK_SIZE)
|
||||
!= (ssize_t)BLKIO_FORTH_BLOCK_SIZE) return BLKIO_EIO;
|
||||
return BLKIO_OK;
|
||||
}
|
||||
|
||||
static int range_flush(blkio_dev_t *dev)
|
||||
{
|
||||
range_t *r = (range_t *)dev->state;
|
||||
if (r->read_only) return BLKIO_OK;
|
||||
return fsync(r->fd) == 0 ? BLKIO_OK : BLKIO_EIO;
|
||||
}
|
||||
|
||||
static int range_info(blkio_dev_t *dev, blkio_info_t *out)
|
||||
{
|
||||
range_t *r = (range_t *)dev->state;
|
||||
out->forth_block_size = BLKIO_FORTH_BLOCK_SIZE;
|
||||
out->total_blocks = r->blocks;
|
||||
out->phys_sector_size = 512u;
|
||||
out->phys_size_bytes = (uint64_t)r->blocks * BLKIO_FORTH_BLOCK_SIZE;
|
||||
out->read_only = (uint8_t)r->read_only;
|
||||
return BLKIO_OK;
|
||||
}
|
||||
|
||||
static const blkio_vtable_t g_range_vt = { range_open, range_close, range_read, range_write, range_flush, range_info };
|
||||
|
||||
extern void sf_time_init(void); /* v3/src/platform/platform_init.c: the clock the volume header's times come from */
|
||||
|
||||
static uint8_t g_ram[(size_t)BLK_RAM_BLOCKS * BLK_FORTH_SIZE];
|
||||
|
||||
static int usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: mkartemis --format|--check IMG --first-lba L --sectors N\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *mode, *img;
|
||||
unsigned long long first_lba, sectors;
|
||||
range_t r;
|
||||
blkio_dev_t dev;
|
||||
blkio_params_t params;
|
||||
uint32_t start_lbn = 0, count = 0;
|
||||
artemis_sig_t sig;
|
||||
int i, format;
|
||||
|
||||
if (argc != 7 || strcmp(argv[3], "--first-lba") != 0 || strcmp(argv[5], "--sectors") != 0) return usage();
|
||||
mode = argv[1];
|
||||
img = argv[2];
|
||||
if (strcmp(mode, "--format") == 0) format = 1;
|
||||
else if (strcmp(mode, "--check") == 0) format = 0;
|
||||
else return usage();
|
||||
first_lba = strtoull(argv[4], NULL, 10);
|
||||
sectors = strtoull(argv[6], NULL, 10);
|
||||
if (first_lba % 2u != 0u || sectors % 2u != 0u || sectors == 0u || sectors / 2u > 0xFFFFFFFFull) {
|
||||
fprintf(stderr, "mkartemis: the partition must start and end on a 1 KiB block (even LBA and sector count)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
r.fd = open(img, format ? O_RDWR : O_RDONLY);
|
||||
if (r.fd < 0) { fprintf(stderr, "mkartemis: %s: %s\n", img, strerror(errno)); return 1; }
|
||||
r.base = (off_t)first_lba * 512;
|
||||
r.blocks = (uint32_t)(sectors / 2u);
|
||||
r.read_only = !format;
|
||||
params.forth_block_size = BLKIO_FORTH_BLOCK_SIZE;
|
||||
params.total_blocks = r.blocks;
|
||||
params.opaque = &r;
|
||||
if (blkio_open(&dev, &g_range_vt, ¶ms) != BLKIO_OK) { fprintf(stderr, "mkartemis: cannot open the range\n"); return 1; }
|
||||
|
||||
sf_time_init();
|
||||
if (blk_subsys_init(g_ram, sizeof(g_ram)) != BLK_OK || blk_subsys_attach_device(&dev) != BLK_OK ||
|
||||
blk_get_device_range(&dev, &start_lbn, &count) != BLK_OK) {
|
||||
fprintf(stderr, "mkartemis: the block subsystem would not take the partition\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (format) {
|
||||
if (artemis_sig_check(&dev, &sig) != ARTEMIS_SIG_BLANK) {
|
||||
fprintf(stderr, "mkartemis: the partition is not blank -- not formatted\n");
|
||||
return 1;
|
||||
}
|
||||
if (blk_subsys_confirm_format(start_lbn) != BLK_OK) { fprintf(stderr, "mkartemis: format failed\n"); return 1; }
|
||||
blk_subsys_shutdown();
|
||||
if (artemis_sig_genesis_stamp(&dev) != 0) { fprintf(stderr, "mkartemis: the signature stamp failed\n"); return 1; }
|
||||
printf("mkartemis: formatted %u blocks, STFR v2, signature stamped\n", r.blocks);
|
||||
} else {
|
||||
blk_volume_meta_t meta;
|
||||
artemis_sig_result_t src;
|
||||
if (blk_get_volume_meta(&meta) != BLK_OK || meta.magic != 0x53544652u || meta.version != 2u) {
|
||||
fprintf(stderr, "mkartemis: no STFR v2 volume header\n");
|
||||
return 1;
|
||||
}
|
||||
src = artemis_sig_check(&dev, &sig);
|
||||
if (src != ARTEMIS_SIG_OK) { fprintf(stderr, "mkartemis: the Artemis signature does not check out (%d)\n", (int)src); return 1; }
|
||||
printf("mkartemis: STFR v2, %u user blocks, signature ok, disk_uuid ", count);
|
||||
for (i = 0; i < 16; i++) printf("%02x", sig.disk_uuid[i]);
|
||||
printf("\n");
|
||||
blk_subsys_shutdown();
|
||||
}
|
||||
close(r.fd);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user