/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. This file is part of the StarForth project. Licensed under the StarForth License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: https://github.com/star.4th@proton.me/StarForth/LICENSE.txt This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. See the License for the specific language governing permissions and limitations under the License. */ /** * artemis_sig.h - Artemis disk signature format (FABRIC-3.md §XXVI follow-on, * 2026-09-13) * * Identifies Artemis's own disk, distinct from an identity thumbdrive's * homeblocks_sig_t -- needed once Artemis's disk stops being found by a * hardcoded PCI virtio-blk vendor/device ID scan (QEMU-only; real hardware * has no reason to expose a virtio-blk PCI device at all, since virtio is a * paravirtualization standard, not something a physical storage controller * speaks) and starts being discovered generically instead, the same way * WIREBIND already discovers identity thumbdrives -- by content signature, * not by which bus happened to present the device. Without a distinct * signature, generic discovery on real hardware (where an identity * thumbdrive and Artemis's own disk could both be attached as USB-MSC * devices simultaneously) would have no way to tell them apart. * * Mirrors homeblocks_sig_t's own structural convention exactly (magic + * version + CRC, one 4KiB devblock, same devblock-1 fixed location) -- * a sibling format, not a field bolted onto homeblocks_sig_t itself: * homeblocks_sig_t's own header comment already states it's "deliberately * narrow in scope" (identity-drive fields only, no spare room -- its * padding is computed to fill exactly 4096 bytes), and Artemis's disk is * conceptually a different kind of thing (one dedicated fleet-owned device, * not one of many candidate identity drives), not a variant of the same one. * * Reserves offset/size pointers to the growable per-VM log-persistence * region (FABRIC-3.md §XXVI follow-on's own log-record work), the same way * homeblocks_sig_t reserves pointers to where the cert and identity source * attach -- this format doesn't need revisiting when that region's own * internal layout is designed. */ #ifndef STARKERNEL_ARTEMIS_SIG_H #define STARKERNEL_ARTEMIS_SIG_H #include #ifdef __cplusplus extern "C" { #endif /*=========================================================================== * Magic Field Packing -- same bit layout convention as HOMEBLOCKS_SIG_PACK * * bits 0..31 : 'ARTM' (0x4D545241 little-endian) -- distinct from * homeblocks_sig_t's 'LAHB', so a generic scan can tell an * Artemis disk apart from an identity thumbdrive by content * alone, regardless of which bus either was found on. * bits 32..39 : version (0 for v0) * bits 40..63 : reserved (zero) *===========================================================================*/ #define ARTEMIS_SIG_MAGIC 0x4D545241ULL /* 'ARTM' */ #define ARTEMIS_SIG_VERSION_0 0 #define ARTEMIS_SIG_PACK(ver) \ (ARTEMIS_SIG_MAGIC | ((uint64_t)(ver) << 32)) #define ARTEMIS_SIG_GET_MAGIC(m) ((uint32_t)((m) & 0xFFFFFFFFULL)) #define ARTEMIS_SIG_GET_VERSION(m) ((uint8_t)(((m) >> 32) & 0xFF)) /* Same devblock-1 (forth-block 4) convention as HOMEBLOCKS_SIG_START_FBLOCK * -- devblock 0 stays reserved for the block-subsystem's own generic * 'STFR'/v2 volume header (block_subsystem.h), same reasoning as * homeblocks_sig.h's own comment on this. No collision risk with an * identity thumbdrive's own homeblocks_sig_t at the same devblock offset -- * they are different physical/virtual devices entirely. */ #define ARTEMIS_SIG_START_FBLOCK 4u /*=========================================================================== * artemis_sig_t - Artemis disk signature header (exactly one 4KiB devblock) *===========================================================================*/ typedef struct { uint64_t magic; /* ARTEMIS_SIG_PACK(...) */ uint8_t disk_uuid[16]; /* Mirrors homeblocks_sig_t's drive_uuid -- * one Artemis disk exists today, but costs * nothing to future-proof the same way. */ uint64_t genesis_time_ns; /* Monotonic timestamp when this signature * was first stamped (the one-time genesis * step, not every boot). */ uint64_t metadata_devblocks; /* Size of the metadata region at the start * of this raw device (sig header + log * region), in 4KiB devblocks -- everything * past this is Artemis's own general * block-storage pool, same "no partition * boundary" convention homeblocks_sig_t * uses for an identity's own pool. */ uint32_t log_region_offset; /* Devblock offset where the growable * per-VM log-persistence region starts; * 0 = not yet allocated. */ uint32_t log_region_devblocks; /* Current reserved size of the log * region, in devblocks -- grows over * time (same growable-reservation * mechanism the metadata fence design * already uses elsewhere), not a single * fixed guess made once at genesis. */ uint64_t hdr_crc; /* Computed over every field above this * one, same boundary/discipline as * homeblocks_sig_compute_crc(). */ /* Padding to keep the header exactly one 4KiB devblock. */ uint8_t _pad[4096 - ( 8 + /* magic */ 16 + /* disk_uuid */ 8 + /* genesis_time_ns */ 8 + /* metadata_devblocks */ 4 + 4 + /* log_region_offset, log_region_devblocks */ 8 /* hdr_crc */ )]; } artemis_sig_t; /* C99-portable compile-time size assertion (no _Static_assert -- that's * C11), same discipline homeblocks_sig.h's own check uses. */ typedef char artemis_sig_size_check[(sizeof(artemis_sig_t) == 4096) ? 1 : -1]; /*=========================================================================== * Signature check (mirrors homeblocks_sig_result_t exactly) *===========================================================================*/ typedef enum { ARTEMIS_SIG_OK = 0, /* magic, version, and crc all check out */ ARTEMIS_SIG_BLANK, /* magic does not match -- blank, foreign, or * an identity thumbdrive (different magic) */ ARTEMIS_SIG_BAD_VERSION, /* magic matches, version unrecognized */ ARTEMIS_SIG_BAD_CRC, /* magic+version match, crc fails -- corrupt * or tampered */ ARTEMIS_SIG_READ_ERROR /* could not read from the device at all */ } artemis_sig_result_t; /* Forward-declared, not included here -- same reasoning as * homeblocks_sig.h's own forward declaration of struct blkio_dev. */ struct blkio_dev; /* * artemis_sig_check - Read and verify the Artemis disk signature header. * Mirrors homeblocks_sig_check()'s own contract exactly (same forth-block * read pattern, same "starting block is a caller-supplied parameter" * separation of concerns). * * @param dev Open block device to read from. * @param sig_start_fblock First of 4 consecutive forth-blocks holding the * 4KB header -- ARTEMIS_SIG_START_FBLOCK for every * real caller today. * @param out_sig On ARTEMIS_SIG_OK, populated with the verified * header. Left unspecified on any other result. * @return ARTEMIS_SIG_OK, or the specific reason for refusal. */ artemis_sig_result_t artemis_sig_check(struct blkio_dev *dev, uint32_t sig_start_fblock, artemis_sig_t *out_sig); /* * artemis_sig_compute_crc - CRC-64 over every field of `sig` up to but not * including hdr_crc itself and the trailing padding. Exposed publicly for * the same reason homeblocks_sig_compute_crc() is: both the check and the * future genesis-stamping step need the identical computation. * * @param sig Header to checksum. hdr_crc and _pad are not read. * @return The CRC-64 value that hdr_crc should hold for `sig` to verify. */ uint64_t artemis_sig_compute_crc(const artemis_sig_t *sig); #ifdef __cplusplus } #endif #endif /* STARKERNEL_ARTEMIS_SIG_H */