@@ -122,9 +122,13 @@ gains the partitions below). Three partitions:
|
||||
- **The minimum stick: 8 GB.** Sticks on the shelf are 16–64 GB; 8 GB is the floor.
|
||||
- **The identity partition stays 500 MiB.** About half a million 1 KiB blocks for Zuse's keys and
|
||||
her own pool.
|
||||
- **Artemis grows to fill the stick at its first boot (§5a),** up to **2 TiB** for the partition
|
||||
(the block layer numbers 1 KiB blocks with 32 bits: 4 TiB is its hard limit; 2 TiB keeps a margin
|
||||
and is past any thumb drive). Space past 2 TiB is left unused, and the boot says so.
|
||||
- **Artemis grows to fill the stick at its first boot (§5a),** up to **256 GiB** for the partition
|
||||
(**amended 2026-10-29**, Captain Bob: "256 GiB is ruled" -- plan
|
||||
`plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md`, R1. This said 2 TiB: the block layer
|
||||
numbers 1 KiB blocks with 32 bits, so 4 TiB is its hard limit, but the block subsystem keeps two
|
||||
bytes of kernel heap per block and the heap is 2 GiB, so a 2 TiB Artemis could not attach; 256 GiB
|
||||
takes about 384 MiB. The stick's Artemis is formatted with a BAM sized for 256 GiB, so growth
|
||||
writes metadata only.) Space past 256 GiB is left unused, and the boot says so.
|
||||
- **A stick under 8 GB** is not grown: it runs at the 2 GiB it was written with, and the boot says
|
||||
so.
|
||||
- **The Artemis partition is formatted when the image is built (my call),** not on first boot:
|
||||
@@ -168,7 +172,7 @@ Before genesis, on a stick whose GPT ends where the 2 GiB image ended and whose
|
||||
first boot of a freshly written stick), the kernel grows Artemis:
|
||||
|
||||
- It moves the backup GPT header and entry array to the disk's end, extends the Artemis partition's
|
||||
last LBA to the end of the usable space (capped at 2 TiB of partition), and rewrites both headers
|
||||
last LBA to the end of the usable space (capped at 256 GiB of partition, amended -- §4), and rewrites both headers
|
||||
with their CRCs (the GPT writer; `INSTALL` reuses it).
|
||||
- It grows Artemis's volume to the partition: its `STFR` header's size, its free map for the new
|
||||
blocks, and its metadata fence (with the genesis marker's slot) moved to the new top, as the block
|
||||
|
||||
+16
-5
@@ -270,6 +270,14 @@ STICK_IMAGE_MIB := 2048
|
||||
STICK_ESP_MIB := 64
|
||||
STICK_IDENT_MIB := 500
|
||||
DATASTICK_MIB := 1536
|
||||
# Growth (STICK.md 5a; plan 2026-10-29-stick-5, R1: "256 GiB is ruled"): a stick of at least
|
||||
# STICK_GROW_MIN_BYTES grows its Artemis partition to fill it, at most STICK_ARTEMIS_CAP_GIB; the
|
||||
# stick's and data stick's Artemis are formatted with a BAM sized for that cap, so growth writes
|
||||
# metadata only. The kernel is built with both (-D, below).
|
||||
STICK_GROW_MIN_BYTES := 8000000000
|
||||
STICK_ARTEMIS_CAP_GIB := 256
|
||||
STICK_ARTEMIS_CAP_SECTORS := 536870912
|
||||
# (256 GiB in 512-byte sectors: keep the two in step)
|
||||
DATASTICK_IMG = $(BUILD_DIR)/datastick.img
|
||||
# STICK_PAIR -- a minted pair (e.g. disk/zuse-scratch) whose identity and Artemis images become
|
||||
# the PC stick's partitions, byte for byte, instead of a blank identity and a fresh Artemis.
|
||||
@@ -706,7 +714,8 @@ endif
|
||||
V4_DEFAULT ?= 1
|
||||
ifeq ($(STARFORTH_V4),1)
|
||||
V4_DEFS := -DSTARFORTH_V4=1 -DSK_V4_DEFAULT=$(V4_DEFAULT) -Iv4/include \
|
||||
-DV4_CELL_BITS=64 -DV4_NODE_WORDS=16384 -DV4_DATA_RING=30 -DV4_RET_RING=31 -DV4_ROM_WORDS=4096
|
||||
-DV4_CELL_BITS=64 -DV4_NODE_WORDS=16384 -DV4_DATA_RING=30 -DV4_RET_RING=31 -DV4_ROM_WORDS=4096 \
|
||||
-DSTICK_GROW_MIN_BYTES=$(STICK_GROW_MIN_BYTES)ULL -DSTICK_ARTEMIS_CAP_GIB=$(STICK_ARTEMIS_CAP_GIB)ULL
|
||||
KERNEL_CFLAGS += $(V4_DEFS)
|
||||
LOADER_CFLAGS += $(V4_DEFS)
|
||||
|
||||
@@ -714,8 +723,8 @@ V4_ENGINE_SRCS := $(addprefix v4/src/,node.c exec.c stack.c iword.c heat.c guard
|
||||
V4_ROM_C := $(BUILD_DIR)/v4_rom_64.c
|
||||
V4_MAP_C := $(BUILD_DIR)/v4_map_64.c
|
||||
|
||||
LOADER_EXTRA_SRCS += $(KERNEL_SRC)/v4/sk_v4.c $(KERNEL_SRC)/v4/sk_v4_identity.c $(KERNEL_SRC)/v4/sk_v4_marker.c
|
||||
KERNEL_EXTRA_SRCS += $(KERNEL_SRC)/v4/sk_v4.c $(KERNEL_SRC)/v4/sk_v4_identity.c $(KERNEL_SRC)/v4/sk_v4_marker.c
|
||||
LOADER_EXTRA_SRCS += $(KERNEL_SRC)/v4/sk_v4.c $(KERNEL_SRC)/v4/sk_v4_identity.c $(KERNEL_SRC)/v4/sk_v4_marker.c $(KERNEL_SRC)/v4/sk_v4_grow.c
|
||||
KERNEL_EXTRA_SRCS += $(KERNEL_SRC)/v4/sk_v4.c $(KERNEL_SRC)/v4/sk_v4_identity.c $(KERNEL_SRC)/v4/sk_v4_marker.c $(KERNEL_SRC)/v4/sk_v4_grow.c
|
||||
# v4/system/boot.c is the boot the hosted v4 system runs too: the ROM
|
||||
# assembles the system, then the capsules from this kernel's own capsule
|
||||
# directory, then the prompt.
|
||||
@@ -816,7 +825,8 @@ $(MKARTEMIS_BIN): $(MKARTEMIS_SRC) $(wildcard v3/include/*.h) kernel/include/sta
|
||||
.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
|
||||
--label DATASTICK --starship $(STICK_IDENT_MIB) --mkartemis $(MKARTEMIS_BIN) --esp-mib 0 \
|
||||
--bam-for $(STICK_ARTEMIS_CAP_SECTORS)
|
||||
|
||||
# zusestick -- Zuse's minted pair as a stick, fresh every time it is made (the ZUSEDISK default).
|
||||
.PHONY: zusestick
|
||||
@@ -1493,7 +1503,8 @@ boot_image: all $(if $(BOARD_STICK),$(MKARTEMIS_BIN))
|
||||
@bash scripts/mkdiskimage.sh --out $(BOARD_OUT)/$(BOARD_IMAGE) --table gpt \
|
||||
$(if $(BOARD_STICK),$(if $(STICK_PAIR),--esp-mib $(STICK_ESP_MIB) --starship-from \
|
||||
$(STICK_PAIR)/zuse-thumb-ident.img $(STICK_PAIR)/artemis.img,--size-mib $(STICK_IMAGE_MIB) \
|
||||
--starship $(STICK_IDENT_MIB) --mkartemis $(MKARTEMIS_BIN) --esp-mib $(STICK_ESP_MIB)), \
|
||||
--starship $(STICK_IDENT_MIB) --mkartemis $(MKARTEMIS_BIN) --esp-mib $(STICK_ESP_MIB) \
|
||||
--bam-for $(STICK_ARTEMIS_CAP_SECTORS)), \
|
||||
--size-mib $(BOOT_IMAGE_SIZE_MIB)) \
|
||||
--label LITHOS \
|
||||
$(LOADER_EFI):/EFI/BOOT/$(EFI_BOOTNAME) \
|
||||
|
||||
@@ -33,6 +33,22 @@ int gpt_read(blkio_dev_t *disk, gpt_part_t *parts, unsigned max, unsigned *count
|
||||
* returned GPT_OK: which disk it was, so a stick can be told from another. */
|
||||
void gpt_disk_guid(uint8_t guid[16]);
|
||||
|
||||
/* The backup header's LBA (header bytes 32..39) of the last gpt_read that
|
||||
* returned GPT_OK: a disk whose backup header is not its last sector is larger
|
||||
* than the table written to it. */
|
||||
uint64_t gpt_alternate_lba(void);
|
||||
|
||||
/* Grow the partition of `type` -- which must be the disk's last -- to the end
|
||||
* of `disk` (plan 2026-10-29-stick-5, Task 2): the backup entry array and
|
||||
* header moved to the disk's last sectors, the partition's last LBA to the
|
||||
* last usable sector before them (on a whole MiB, at most `max_part_sectors`
|
||||
* long), both headers rewritten with their CRCs -- the backup first, so a
|
||||
* write torn between them leaves the old primary valid -- and the protective
|
||||
* MBR's size. GPT_OK with `*new_last_lba` the partition's last LBA (unchanged,
|
||||
* and nothing written, when the backup header is already the disk's last
|
||||
* sector); GPT_BAD or GPT_EIO otherwise. */
|
||||
int gpt_grow_last(blkio_dev_t *disk, const uint8_t type[16], uint64_t max_part_sectors, uint64_t *new_last_lba);
|
||||
|
||||
/* The index of the first partition of `type`, or -1. */
|
||||
int gpt_find(const gpt_part_t *parts, unsigned count, const uint8_t type[16]);
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/* sk_v4_grow.h -- Artemis grows to fill the stick at its first boot
|
||||
* (docs/v4.0.0/STICK.md 5a; plan 2026-10-29-stick-5, Task 2).
|
||||
*
|
||||
* Built only with STARFORTH_V4=1 (Kconfig.kernel).
|
||||
*/
|
||||
#ifndef STARKERNEL_V4_SK_V4_GROW_H
|
||||
#define STARKERNEL_V4_SK_V4_GROW_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "blkio.h"
|
||||
|
||||
/* How far the Artemis partition `art` may grow, in 512-byte sectors: no
|
||||
* further than `cap_sectors`, nor than its volume's BAM can track. 0 when
|
||||
* `art` holds no STFR v2 volume. Reads only. */
|
||||
uint64_t sk_v4_grow_cap_sectors(blkio_dev_t *art, uint64_t cap_sectors);
|
||||
|
||||
/* Grow the volume on `art` to fill its partition: its fence (the Artemis
|
||||
* signature, Zuse's genesis marker) moved to the new top, then its header.
|
||||
* Metadata only. 1 when grown, 0 when it already fills the partition, -1 on
|
||||
* an error -- the old header then still names the old volume, whole. */
|
||||
int sk_v4_grow_artemis(blkio_dev_t *art);
|
||||
|
||||
#endif /* STARKERNEL_V4_SK_V4_GROW_H */
|
||||
+125
-2
@@ -7,8 +7,13 @@
|
||||
* a block device of a StarshipOS partition: its block 0 is the partition's
|
||||
* first 1 KiB, and nothing past its end can be reached through it. The
|
||||
* identity and Artemis formats inside a partition are exactly those of a raw
|
||||
* drive today. Reads only. 512-byte logical sectors only (the stick and its
|
||||
* data stick); docs/v4.0.0/plans/2026-10-26-stick-2-gpt-reader.md.
|
||||
* drive today. 512-byte logical sectors only (the stick and its data stick);
|
||||
* docs/v4.0.0/plans/2026-10-26-stick-2-gpt-reader.md.
|
||||
*
|
||||
* The writer (plan 2026-10-29-stick-5, Task 2; STICK.md 5a): the stick's last
|
||||
* partition grown to the end of a disk larger than the image written to it --
|
||||
* the backup header and entry array moved to the disk's end, both headers
|
||||
* rewritten with their CRCs, the backup before the primary.
|
||||
*/
|
||||
#include "starkernel/gpt.h"
|
||||
#include "console.h"
|
||||
@@ -51,6 +56,7 @@ static uint64_t le64(const uint8_t *p) { return (uint64_t)le32(p) | (uint64_t)le
|
||||
static uint8_t g_gpt_hdr_block[BLKIO_FORTH_BLOCK_SIZE];
|
||||
static uint8_t g_gpt_entries[GPT_ENTRIES_MAX];
|
||||
static uint8_t g_gpt_disk_guid[16]; /* the DiskGUID of the last gpt_read that gave GPT_OK */
|
||||
static uint64_t g_gpt_alternate_lba; /* and its backup header's LBA */
|
||||
|
||||
int gpt_read(blkio_dev_t *disk, gpt_part_t *parts, unsigned max, unsigned *count)
|
||||
{
|
||||
@@ -125,6 +131,7 @@ int gpt_read(blkio_dev_t *disk, gpt_part_t *parts, unsigned max, unsigned *count
|
||||
}
|
||||
*count = n;
|
||||
memcpy(g_gpt_disk_guid, h + 56, 16);
|
||||
g_gpt_alternate_lba = le64(h + 32);
|
||||
return GPT_OK;
|
||||
}
|
||||
|
||||
@@ -140,6 +147,122 @@ int gpt_find(const gpt_part_t *parts, unsigned count, const uint8_t type[16])
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---- the writer: growing the last partition to the disk's end ---------- */
|
||||
|
||||
static void put_le32(uint8_t *p, uint32_t v) { p[0] = (uint8_t)v; p[1] = (uint8_t)(v >> 8); p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24); }
|
||||
static void put_le64(uint8_t *p, uint64_t v) { put_le32(p, (uint32_t)v); put_le32(p + 4, (uint32_t)(v >> 32)); }
|
||||
|
||||
static uint8_t g_gpt_rmw[BLKIO_FORTH_BLOCK_SIZE];
|
||||
|
||||
/* Write `n` 512-byte sectors from `src` at sector `lba`: each through a
|
||||
* read-modify-write of the 1 KiB block that holds it, so a sector at an odd
|
||||
* LBA (the backup header, the backup entry array) is written alone. */
|
||||
static int put_sectors(blkio_dev_t *disk, uint64_t lba, const uint8_t *src, uint32_t n)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
uint64_t s = lba + i;
|
||||
uint32_t blk = (uint32_t)(s / 2u);
|
||||
if (blkio_read(disk, blk, g_gpt_rmw) != BLKIO_OK) return -1;
|
||||
memcpy(g_gpt_rmw + (s % 2u) * GPT_SECTOR, src + (size_t)i * GPT_SECTOR, GPT_SECTOR);
|
||||
if (blkio_write(disk, blk, g_gpt_rmw) != BLKIO_OK) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t gpt_alternate_lba(void)
|
||||
{
|
||||
return g_gpt_alternate_lba;
|
||||
}
|
||||
|
||||
int gpt_grow_last(blkio_dev_t *disk, const uint8_t type[16], uint64_t max_part_sectors, uint64_t *new_last_lba)
|
||||
{
|
||||
static gpt_part_t parts[16];
|
||||
static uint8_t hdr[GPT_SECTOR], bak[GPT_SECTOR];
|
||||
const uint8_t *h = g_gpt_hdr_block + GPT_SECTOR;
|
||||
uint8_t *mbr = g_gpt_hdr_block, *e = (uint8_t *)0;
|
||||
uint64_t disk_sectors, alt, ent_lba, new_alt, new_ent, new_last_usable, first, last, want, top = 0;
|
||||
uint32_t nent, esize, ent_sectors, i;
|
||||
unsigned count;
|
||||
size_t ebytes;
|
||||
int rc;
|
||||
|
||||
rc = gpt_read(disk, parts, 16u, &count);
|
||||
if (rc != GPT_OK) return rc == GPT_NONE ? GPT_BAD : rc;
|
||||
nent = le32(h + 80);
|
||||
esize = le32(h + 84);
|
||||
ebytes = (size_t)nent * esize;
|
||||
ent_sectors = (uint32_t)((ebytes + GPT_SECTOR - 1u) / GPT_SECTOR);
|
||||
ent_lba = le64(h + 72);
|
||||
alt = le64(h + 32);
|
||||
disk_sectors = (uint64_t)disk->total_blocks * (BLKIO_FORTH_BLOCK_SIZE / GPT_SECTOR);
|
||||
|
||||
/* the partition of `type`, which must be the last on the disk */
|
||||
for (i = 0; i < nent; i++) {
|
||||
uint8_t *x = g_gpt_entries + (size_t)i * esize;
|
||||
static const uint8_t zero[16];
|
||||
if (memcmp(x, zero, 16) == 0) continue;
|
||||
if (le64(x + 40) > top) top = le64(x + 40);
|
||||
if (!e && memcmp(x, type, 16) == 0) e = x;
|
||||
}
|
||||
if (!e) return GPT_BAD;
|
||||
first = le64(e + 32);
|
||||
last = le64(e + 40);
|
||||
*new_last_lba = last;
|
||||
if (alt == disk_sectors - 1u) return GPT_OK; /* already ends at the disk's end */
|
||||
if (alt > disk_sectors - 1u || last != top) return GPT_BAD;
|
||||
|
||||
/* the backup entry array and header at the disk's end; the partition to
|
||||
* the last usable sector before them, on whole MiB, at most max sectors */
|
||||
new_alt = disk_sectors - 1u;
|
||||
new_ent = new_alt - ent_sectors;
|
||||
new_last_usable = new_ent - 1u;
|
||||
if (new_last_usable < last) return GPT_BAD;
|
||||
want = new_last_usable - first + 1u;
|
||||
if (want > max_part_sectors) want = max_part_sectors;
|
||||
want -= want % 2048u;
|
||||
if (first + want - 1u > last) {
|
||||
last = first + want - 1u;
|
||||
put_le64(e + 40, last);
|
||||
}
|
||||
|
||||
/* the primary header, then the backup: each with its own LBAs and CRC */
|
||||
memcpy(hdr, h, GPT_SECTOR);
|
||||
put_le64(hdr + 32, new_alt);
|
||||
put_le64(hdr + 48, new_last_usable);
|
||||
put_le32(hdr + 88, gpt_crc32(g_gpt_entries, ebytes));
|
||||
memcpy(bak, hdr, GPT_SECTOR);
|
||||
put_le64(bak + 24, new_alt);
|
||||
put_le64(bak + 32, 1u);
|
||||
put_le64(bak + 72, new_ent);
|
||||
put_le32(hdr + 16, 0u);
|
||||
put_le32(hdr + 16, gpt_crc32(hdr, le32(hdr + 12)));
|
||||
put_le32(bak + 16, 0u);
|
||||
put_le32(bak + 16, gpt_crc32(bak, le32(bak + 12)));
|
||||
|
||||
/* the backup before the primary: a write torn between them leaves the old
|
||||
* primary, which still checks out, and the next boot grows again */
|
||||
if (put_sectors(disk, new_ent, g_gpt_entries, ent_sectors) != 0 ||
|
||||
put_sectors(disk, new_alt, bak, 1u) != 0 || disk->vt->flush(disk) != BLKIO_OK)
|
||||
return GPT_EIO;
|
||||
if (put_sectors(disk, ent_lba, g_gpt_entries, ent_sectors) != 0 ||
|
||||
put_sectors(disk, 1u, hdr, 1u) != 0 || disk->vt->flush(disk) != BLKIO_OK)
|
||||
return GPT_EIO;
|
||||
|
||||
/* the protective MBR's partition covers the disk (as many sectors as fit) */
|
||||
for (i = 0; i < 4u; i++) {
|
||||
uint8_t *p = mbr + 446u + 16u * i;
|
||||
if (p[4] == 0xEEu) {
|
||||
put_le32(p + 12, disk_sectors - 1u > 0xFFFFFFFFu ? 0xFFFFFFFFu : (uint32_t)(disk_sectors - 1u));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (put_sectors(disk, 0u, mbr, 1u) != 0 || disk->vt->flush(disk) != BLKIO_OK) return GPT_EIO;
|
||||
|
||||
*new_last_lba = last;
|
||||
return GPT_OK;
|
||||
}
|
||||
|
||||
/* ---- a partition as a blkio device ------------------------------------- */
|
||||
|
||||
static int part_open(blkio_dev_t *dev, const blkio_params_t *p)
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/* sk_v4_grow.c -- Artemis grows to fill the stick at its first boot
|
||||
* (docs/v4.0.0/STICK.md 5a; plan 2026-10-29-stick-5, Task 2).
|
||||
*
|
||||
* Metadata only: the volume's header, and its fence -- the top-of-volume
|
||||
* system metadata, which holds the Artemis signature and Zuse's genesis
|
||||
* marker (artemis_sig.c, blk_meta_zone_read/write) -- moved to the new top.
|
||||
* The volume's data blocks are never written, and its BAM is not resized: the
|
||||
* image is built with a BAM sized for the cap (mkartemis --bam-for), so the
|
||||
* new blocks are tracked already and read as free.
|
||||
*
|
||||
* The block subsystem places a volume's fence by its device's size, not by
|
||||
* its header (blk_format_or_load_disk), so a volume always fills its
|
||||
* partition: the partition is grown no further than the BAM can track
|
||||
* (sk_v4_grow_cap_sectors), then the volume to the partition.
|
||||
*/
|
||||
#include "starkernel/v4/sk_v4_grow.h"
|
||||
#include "block_subsystem.h"
|
||||
#include <string.h>
|
||||
|
||||
static union {
|
||||
uint8_t bytes[4096];
|
||||
blk_volume_meta_t meta;
|
||||
} g_hdr;
|
||||
static uint8_t g_move[4096];
|
||||
|
||||
static int dev_rw4k(blkio_dev_t *dev, uint64_t devblock, uint8_t *buf, int write)
|
||||
{
|
||||
uint32_t base = (uint32_t)devblock * 4u, k;
|
||||
for (k = 0; k < 4u; k++) {
|
||||
int rc = write ? blkio_write(dev, base + k, buf + k * 1024u)
|
||||
: blkio_read(dev, base + k, buf + k * 1024u);
|
||||
if (rc != BLKIO_OK) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_header(blkio_dev_t *art)
|
||||
{
|
||||
if (dev_rw4k(art, 0u, g_hdr.bytes, 0) != 0) return -1;
|
||||
if (g_hdr.meta.magic != 0x53544652u || g_hdr.meta.version != 2u ||
|
||||
g_hdr.meta.bam_devblocks == 0u || g_hdr.meta.meta_fence_blocks == 0u)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The most devblocks a volume with this header's BAM can be: no more Forth
|
||||
* blocks in its payload than the BAM tracks (compute_totals_from_B). */
|
||||
static uint64_t bam_cover_devblocks(const blk_volume_meta_t *m)
|
||||
{
|
||||
uint64_t tracked = 32768ULL * m->bam_devblocks;
|
||||
return tracked / 3u + 1u + m->bam_devblocks + m->reloc_devblocks + m->meta_fence_blocks;
|
||||
}
|
||||
|
||||
uint64_t sk_v4_grow_cap_sectors(blkio_dev_t *art, uint64_t cap_sectors)
|
||||
{
|
||||
uint64_t cover;
|
||||
if (read_header(art) != 0) return 0;
|
||||
cover = bam_cover_devblocks(&g_hdr.meta) * 8u; /* 4 KiB devblocks, in 512-byte sectors */
|
||||
return cover < cap_sectors ? cover : cap_sectors;
|
||||
}
|
||||
|
||||
int sk_v4_grow_artemis(blkio_dev_t *art)
|
||||
{
|
||||
blkio_info_t info;
|
||||
uint64_t old_t, new_t, f, k, old_total;
|
||||
|
||||
if (read_header(art) != 0) return -1;
|
||||
if (blkio_info(art, &info) != BLKIO_OK) return -1;
|
||||
old_t = g_hdr.meta.total_devblocks;
|
||||
new_t = info.total_blocks / 4u;
|
||||
if (new_t <= old_t) return 0; /* not grown: it fills its partition */
|
||||
if (new_t > bam_cover_devblocks(&g_hdr.meta)) return -1;
|
||||
f = g_hdr.meta.meta_fence_blocks;
|
||||
/* the old and new fences never overlap (a partition grows by whole MiB,
|
||||
* 256 devblocks, past a 128-devblock fence), so a copy torn by a power
|
||||
* loss is simply done again from the old top at the next boot */
|
||||
if (f >= old_t || new_t - old_t < f) return -1;
|
||||
|
||||
/* the fence to the new top, devblock by devblock */
|
||||
for (k = 0; k < f; k++) {
|
||||
if (dev_rw4k(art, old_t - 1u - k, g_move, 0) != 0) return -1;
|
||||
if (dev_rw4k(art, new_t - 1u - k, g_move, 1) != 0) return -1;
|
||||
}
|
||||
if (blkio_flush(art) != BLKIO_OK) return -1;
|
||||
|
||||
/* the header last: until it is written, the old header names the old top */
|
||||
old_total = g_hdr.meta.total_blocks;
|
||||
g_hdr.meta.total_devblocks = new_t;
|
||||
blk_volume_compute_totals(&g_hdr.meta);
|
||||
g_hdr.meta.free_blocks += g_hdr.meta.total_blocks - old_total;
|
||||
if (dev_rw4k(art, 0u, g_hdr.bytes, 1) != 0) return -1;
|
||||
if (blkio_flush(art) != BLKIO_OK) return -1;
|
||||
return 1;
|
||||
}
|
||||
@@ -22,6 +22,12 @@
|
||||
* Zuse exists -- reads her back, then writes the version 2 marker
|
||||
* (sk_v4_marker.c) naming her.
|
||||
*
|
||||
* Growth (plan 2026-10-29-stick-5, Task 2; STICK.md 5a): a stick of at least
|
||||
* 8 GB whose GPT ends short of the disk -- a stick larger than the image
|
||||
* written to it -- has its Artemis partition grown to fill it (capped at
|
||||
* 256 GiB, and at what its BAM tracks: sk_v4_grow.c), then Artemis's volume
|
||||
* grown to the partition, before anything on it is read. Metadata only.
|
||||
*
|
||||
* Not here (the plan's "not in this gate"): WIREBIND identities, EJECT,
|
||||
* ACL-ZUSE-BOOT.
|
||||
*/
|
||||
@@ -39,6 +45,7 @@
|
||||
#include "starkernel/kbd_input.h"
|
||||
#include "starkernel/gpt.h"
|
||||
#include "starkernel/v4/sk_v4_marker.h"
|
||||
#include "starkernel/v4/sk_v4_grow.h"
|
||||
#ifdef ARCH_AMD64
|
||||
#include "starkernel/ioapic.h"
|
||||
#include "starkernel/i8042.h"
|
||||
@@ -149,6 +156,45 @@ static int sk_v4_is_this_stick(unsigned nparts)
|
||||
return !g_stick_in;
|
||||
}
|
||||
|
||||
/* Growth's limits, from kernel/Makefile (-D): the stick at least this big,
|
||||
* Artemis's partition at most this big */
|
||||
#define SK_V4_GROW_MIN_BYTES STICK_GROW_MIN_BYTES
|
||||
#define SK_V4_CAP_SECTORS (STICK_ARTEMIS_CAP_GIB * 2097152ULL)
|
||||
|
||||
/* This system's stick, its GPT just read (g_gpt_parts, *nparts): when the
|
||||
* stick is larger than its GPT (its backup header is not the disk's last
|
||||
* sector) and at least 8 GB, the Artemis partition is grown to fill it, and
|
||||
* the GPT read again. Returns 0, or -1 when the GPT cannot be read again. */
|
||||
static int sk_v4_grow_stick(sk_v4_drive_t *d, unsigned *nparts)
|
||||
{
|
||||
static int said_small;
|
||||
uint64_t disk_sectors = (uint64_t)d->raw.total_blocks * (BLKIO_FORTH_BLOCK_SIZE / 512u);
|
||||
uint64_t cap, new_last, first;
|
||||
int ai = gpt_find(g_gpt_parts, *nparts, gpt_type_starship_artemis);
|
||||
|
||||
if (ai < 0 || gpt_alternate_lba() == disk_sectors - 1u) return 0; /* the GPT fills the stick */
|
||||
if (disk_sectors * 512u < SK_V4_GROW_MIN_BYTES) {
|
||||
if (!said_small) {
|
||||
console_println("Artemis: the stick is under 8 GB -- not grown");
|
||||
said_small = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
first = g_gpt_parts[ai].first_lba;
|
||||
if (gpt_part_open(&d->art, &d->art_state, &d->raw, &g_gpt_parts[ai]) != BLKIO_OK) return 0;
|
||||
cap = sk_v4_grow_cap_sectors(&d->art, SK_V4_CAP_SECTORS);
|
||||
if (cap == 0) return 0; /* no Artemis volume: the signature check refuses it */
|
||||
if (gpt_grow_last(&d->raw, gpt_type_starship_artemis, cap, &new_last) != GPT_OK)
|
||||
console_println("GPT: the stick's table could not be grown");
|
||||
else if (new_last - first + 1u >= SK_V4_CAP_SECTORS && first + SK_V4_CAP_SECTORS + 2048u < disk_sectors)
|
||||
console_println("Artemis: past 256 GiB of the stick is left unused");
|
||||
if (gpt_read(&d->raw, g_gpt_parts, SK_V4_GPT_PARTS, nparts) != GPT_OK ||
|
||||
gpt_find(g_gpt_parts, *nparts, gpt_type_starship_identity) < 0 ||
|
||||
gpt_find(g_gpt_parts, *nparts, gpt_type_starship_artemis) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Zuse's session begins on @p dev: the console is hers, and the screen with
|
||||
* it (docs/v4.0.0/STICK.md 2). @p line says how she was found. */
|
||||
static void sk_v4_login(blkio_dev_t *dev, const uint8_t seed[32], const uint8_t pubkey[32],
|
||||
@@ -241,6 +287,10 @@ static int sk_v4_drive_arrived(sk_v4_drive_t *d)
|
||||
console_println("USB: a drive that is not this system's stick -- not used");
|
||||
return 1;
|
||||
}
|
||||
if (sk_v4_grow_stick(d, &nparts) != 0) {
|
||||
console_println("GPT: the stick's grown table does not read back");
|
||||
return 1;
|
||||
}
|
||||
if (gpt_part_open(&d->art, &d->art_state, &d->raw,
|
||||
&g_gpt_parts[gpt_find(g_gpt_parts, nparts, gpt_type_starship_artemis)]) != BLKIO_OK ||
|
||||
gpt_part_open(&d->part, &d->part_state, &d->raw,
|
||||
@@ -249,6 +299,13 @@ static int sk_v4_drive_arrived(sk_v4_drive_t *d)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Artemis's volume fills its partition, grown with it (STICK.md 5a) */
|
||||
{
|
||||
int g = sk_v4_grow_artemis(&d->art);
|
||||
if (g > 0) console_println("Artemis: grown to fill the stick");
|
||||
else if (g < 0) console_println("Artemis: the stick's volume could not be grown");
|
||||
}
|
||||
|
||||
/* Artemis first: formatted and signed at build (STICK.md 4); a
|
||||
* signature that does not check out is not used, nor is the stick */
|
||||
if (artemis_sig_check(&d->art, &asig) != ARTEMIS_SIG_OK) {
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
[2J[01;01H[=3h[2J[01;01H[2J[01;01H[=3h[2J[01;01H[2J[01;01H[=3h[2J[01;01HBdsDxe: loading Boot0001 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:03.0-1" from PciRoot(0x0)/Pci(0x3,0x0)/USB(0x0,0x0)
|
||||
BdsDxe: starting Boot0001 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:03.0-1" from PciRoot(0x0)/Pci(0x3,0x0)/USB(0x0,0x0)
|
||||
[2J[01;01H[=3h[2J[01;01HStarKernel 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: from starforth.cfg
|
||||
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 v4.0.0-alpha.3 amd64
|
||||
Architecture: amd64
|
||||
Build: Nov 8 2026 11:58:08
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a 16550 at port 0x00000000000003f8 (COM1, probed)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 128
|
||||
Total memory: 1023 MB
|
||||
Usable memory: 965 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 248623
|
||||
Free pages : 247096
|
||||
Used pages : 1527
|
||||
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=2048803536 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=980690917, tick_hz=100, initial_count=9806909
|
||||
APIC Timer: configured (masked, ready to start)
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
Boot disk: a StarshipOS stick
|
||||
System: StarForth v4 (system=v4)
|
||||
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
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
PCI: ECAM mapped (amd64)
|
||||
virtio-rng: no device on PCI bus 0
|
||||
rng: backend = rdrand
|
||||
entropy: ready
|
||||
virtio-input: no device on PCI bus 0
|
||||
Starting heartbeat...
|
||||
APIC Timer: started (LVT=0x00020020 ICR=9806909)
|
||||
I/O APIC: keyboard IRQ1 unmasked
|
||||
Heartbeat running.
|
||||
blkio_usb: MSC device ready
|
||||
Artemis: grown to fill the stick
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 16230636740] blk: disk 'StarForth Volume' v2 LBN 3072..12132441 (12129370 us
|
||||
Artemis: the stick's partition attached
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 16247512130] blk: disk 'StarForth Volume' v2 LBN 12132442..12515983 (383542
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 16269128656] MINT verify: identity reads back correctly
|
||||
[38;2;255;165;0m[Hera][39m Zuse: genesis minted onto attached thumbdrive
|
||||
[38;2;255;165;0m[zuse@Hera][39m [38;2;85;255;255mok> [39m
|
||||
@@ -0,0 +1,163 @@
|
||||
[2J[01;01H[=3h[2J[01;01H[2J[01;01H[=3h[2J[01;01H[2J[01;01H[=3h[2J[01;01HBdsDxe: loading Boot0001 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:03.0-1" from PciRoot(0x0)/Pci(0x3,0x0)/USB(0x0,0x0)
|
||||
BdsDxe: starting Boot0001 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:03.0-1" from PciRoot(0x0)/Pci(0x3,0x0)/USB(0x0,0x0)
|
||||
[2J[01;01H[=3h[2J[01;01HStarKernel 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: from starforth.cfg
|
||||
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 v4.0.0-alpha.3 amd64
|
||||
Architecture: amd64
|
||||
Build: Nov 8 2026 11:58:08
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a 16550 at port 0x00000000000003f8 (COM1, probed)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 128
|
||||
Total memory: 1023 MB
|
||||
Usable memory: 965 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 248623
|
||||
Free pages : 247096
|
||||
Used pages : 1527
|
||||
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=2031442736 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=975597517, tick_hz=100, initial_count=9755975
|
||||
APIC Timer: configured (masked, ready to start)
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
Boot disk: a StarshipOS stick
|
||||
System: StarForth v4 (system=v4)
|
||||
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)
|
||||
PARRITY: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
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
PCI: ECAM mapped (amd64)
|
||||
virtio-rng: no device on PCI bus 0
|
||||
rng: backend = rdrand
|
||||
entropy: ready
|
||||
virtio-input: no device on PCI bus 0
|
||||
Starting heartbeat...
|
||||
APIC Timer: started (LVT=0x00020020 ICR=9755975)
|
||||
I/O APIC: keyboard IRQ1 unmasked
|
||||
Heartbeat running.
|
||||
blkio_usb: MSC device ready
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 15850556752] blk: disk 'StarForth Volume' v2 LBN 3072..12132441 (12129370 us
|
||||
Artemis: the stick's partition attached
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 15868168832] blk: disk 'StarForth Volume' v2 LBN 12132442..12515983 (383542
|
||||
[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> [39m
|
||||
@@ -0,0 +1,165 @@
|
||||
[2J[01;01H[=3h[2J[01;01H[2J[01;01H[=3h[2J[01;01H[2J[01;01H[=3h[2J[01;01HBdsDxe: loading Boot0001 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:03.0-1" from PciRoot(0x0)/Pci(0x3,0x0)/USB(0x0,0x0)
|
||||
BdsDxe: starting Boot0001 "UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:03.0-1" from PciRoot(0x0)/Pci(0x3,0x0)/USB(0x0,0x0)
|
||||
[2J[01;01H[=3h[2J[01;01HStarKernel 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: from starforth.cfg
|
||||
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 v4.0.0-alpha.3 amd64
|
||||
Architecture: amd64
|
||||
Build: Nov 8 2026 12:01:37
|
||||
|
||||
UEFI BootServices: EXITED
|
||||
Console: serial line is a 16550 at port 0x00000000000003f8 (COM1, probed)
|
||||
|
||||
=== StarKernel Boot Information ===
|
||||
Memory map entries: 128
|
||||
Total memory: 1023 MB
|
||||
Usable memory: 965 MB
|
||||
===================================
|
||||
|
||||
PMM initialized.
|
||||
PMM statistics:
|
||||
Total pages: 248623
|
||||
Free pages : 247096
|
||||
Used pages : 1527
|
||||
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=2090125821 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=999200110, tick_hz=100, initial_count=9992001
|
||||
APIC Timer: configured (masked, ready to start)
|
||||
Heartbeat: init done
|
||||
Kernel initialization complete.
|
||||
Boot successful!
|
||||
|
||||
Boot disk: a StarshipOS stick
|
||||
System: StarForth v4 (system=v4)
|
||||
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
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 0] blk: raw device LBN 2048..3071 (1024 blocks)
|
||||
PCI: init...
|
||||
PCI: ECAM mapped (amd64)
|
||||
virtio-rng: no device on PCI bus 0
|
||||
rng: backend = rdrand
|
||||
entropy: ready
|
||||
virtio-input: no device on PCI bus 0
|
||||
Starting heartbeat...
|
||||
APIC Timer: started (LVT=0x00020020 ICR=9992001)
|
||||
I/O APIC: keyboard IRQ1 unmasked
|
||||
Heartbeat running.
|
||||
blkio_usb: MSC device ready
|
||||
Artemis: the stick is under 8 GB -- not grown
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 15571534696] blk: disk 'StarForth Volume' v2 LBN 3072..1122393 (1119322 user
|
||||
Artemis: the stick's partition attached
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 15591872270] blk: disk 'StarForth Volume' v2 LBN 1122394..1505935 (383542 us
|
||||
[32m[HADES][INFO ] [0m[KRELTSC: 15623585180] MINT verify: identity reads back correctly
|
||||
[38;2;255;165;0m[Hera][39m Zuse: genesis minted onto attached thumbdrive
|
||||
[38;2;255;165;0m[zuse@Hera][39m [38;2;85;255;255mok> [39m
|
||||
@@ -17,11 +17,12 @@
|
||||
# --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
|
||||
# --starship IDENT_MIB --mkartemis TOOL --esp-mib E [--bam-for SECTORS]
|
||||
# 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
|
||||
# formatted and signed by TOOL (tools/mkartemis.c) -- with --bam-for, its BAM sized for an Artemis
|
||||
# of SECTORS, so it can grow that far on a larger stick (STICK.md 5a). Every partition starts and
|
||||
# ends on a whole MiB, so on 1 KiB blocks, as the kernel's GPT reader needs.
|
||||
#
|
||||
# Zuse's minted pair as a stick (docs/v4.0.0/plans/2026-10-27-stick-4-one-disk.md, Task 1):
|
||||
@@ -38,7 +39,7 @@
|
||||
# root, no loop devices.
|
||||
set -euo pipefail
|
||||
|
||||
OUT="" TABLE="" SIZE_MIB="" LABEL="" IDENT_MIB="" MKARTEMIS="" ESP_MIB="" FROM_IDENT="" FROM_ART=""
|
||||
OUT="" TABLE="" SIZE_MIB="" LABEL="" IDENT_MIB="" MKARTEMIS="" ESP_MIB="" FROM_IDENT="" FROM_ART="" BAM_FOR=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--out) OUT="$2"; shift 2 ;;
|
||||
@@ -48,6 +49,7 @@ while [ $# -gt 0 ]; do
|
||||
--starship) IDENT_MIB="$2"; shift 2 ;;
|
||||
--mkartemis) MKARTEMIS="$2"; shift 2 ;;
|
||||
--esp-mib) ESP_MIB="$2"; shift 2 ;;
|
||||
--bam-for) BAM_FOR="$2"; shift 2 ;;
|
||||
--starship-from) FROM_IDENT="$2"; FROM_ART="$3"; shift 3 ;;
|
||||
--) shift; break ;;
|
||||
-*) echo "mkdiskimage.sh: unknown option $1" >&2; exit 2 ;;
|
||||
@@ -119,7 +121,8 @@ if [ -n "$IDENT_MIB" ]; then
|
||||
dd if="$FROM_IDENT" of="$OUT" bs=1M seek=$(( IDENT_START / 2048 )) conv=notrunc,sparse status=none
|
||||
dd if="$FROM_ART" of="$OUT" bs=1M seek=$(( ART_START / 2048 )) conv=notrunc,sparse status=none
|
||||
else
|
||||
"$MKARTEMIS" --format "$OUT" --first-lba "$ART_START" --sectors "$ART_SECTORS" >/dev/null || {
|
||||
"$MKARTEMIS" --format "$OUT" --first-lba "$ART_START" --sectors "$ART_SECTORS" \
|
||||
${BAM_FOR:+--bam-for "$BAM_FOR"} >/dev/null || {
|
||||
echo "mkdiskimage.sh: formatting Artemis failed" >&2; rm -f "$OUT"; exit 1; }
|
||||
fi
|
||||
if [ "$ESP_MIB" = 0 ]; then
|
||||
|
||||
+22
-6
@@ -10,10 +10,14 @@
|
||||
* 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 --format IMG --first-lba L --sectors N [--bam-for M]
|
||||
* mkartemis --check IMG --first-lba L --sectors N
|
||||
*
|
||||
* L and N count 512-byte sectors; both must be even (1 KiB blocks).
|
||||
* L, N and M count 512-byte sectors; L and N must be even (1 KiB blocks).
|
||||
* --bam-for M sizes the volume's BAM as for a volume of M sectors, so it can
|
||||
* grow that far on a larger stick with no BAM to move (docs/v4.0.0/STICK.md
|
||||
* 5a; plan 2026-10-29-stick-5, R1 and Task 2). --check reports the BAM's
|
||||
* size in 4 KiB devblocks.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <errno.h>
|
||||
@@ -111,7 +115,7 @@ 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");
|
||||
fprintf(stderr, "usage: mkartemis --format|--check IMG --first-lba L --sectors N [--bam-for M]\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -140,6 +144,8 @@ static int attach(blkio_dev_t *dev, uint32_t *start_lbn, uint32_t *count)
|
||||
* header is read from the disk itself and judged as attach judges it
|
||||
* (block_subsystem.c blk_format_or_load_disk): blk_get_volume_meta would give
|
||||
* the geometry computed in memory for a blank disk, magic and all. */
|
||||
static uint32_t g_bam_devblocks; /* the BAM's size, as check_volume read it */
|
||||
|
||||
static int check_volume(blkio_dev_t *dev, uint32_t *count, artemis_sig_t *sig)
|
||||
{
|
||||
static uint8_t hdr[BLK_DEVICE_SECTOR];
|
||||
@@ -160,6 +166,7 @@ static int check_volume(blkio_dev_t *dev, uint32_t *count, artemis_sig_t *sig)
|
||||
fprintf(stderr, "mkartemis: the Artemis signature does not check out (%d)\n", (int)src);
|
||||
else
|
||||
rc = 0;
|
||||
g_bam_devblocks = meta.bam_devblocks;
|
||||
blk_subsys_shutdown();
|
||||
return rc;
|
||||
}
|
||||
@@ -167,7 +174,7 @@ static int check_volume(blkio_dev_t *dev, uint32_t *count, artemis_sig_t *sig)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *mode, *img;
|
||||
unsigned long long first_lba, sectors;
|
||||
unsigned long long first_lba, sectors, bam_for = 0;
|
||||
range_t r;
|
||||
blkio_dev_t dev;
|
||||
blkio_params_t params;
|
||||
@@ -175,7 +182,8 @@ int main(int argc, char **argv)
|
||||
artemis_sig_t sig;
|
||||
int i, format;
|
||||
|
||||
if (argc != 7 || strcmp(argv[3], "--first-lba") != 0 || strcmp(argv[5], "--sectors") != 0) return usage();
|
||||
if ((argc != 7 && argc != 9) || 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;
|
||||
@@ -185,6 +193,12 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "mkartemis: --first-lba and --sectors take a number of sectors\n");
|
||||
return 1;
|
||||
}
|
||||
if (argc == 9) {
|
||||
if (!format || strcmp(argv[7], "--bam-for") != 0 || parse_count(argv[8], &bam_for) != 0 || bam_for < sectors) {
|
||||
fprintf(stderr, "mkartemis: --bam-for takes a number of sectors, at least --sectors, with --format\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
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;
|
||||
@@ -202,6 +216,7 @@ int main(int argc, char **argv)
|
||||
|
||||
sf_time_init();
|
||||
if (format) {
|
||||
blk_subsys_set_format_bam_for(bam_for / 8u); /* sectors -> 4 KiB devblocks */
|
||||
if (attach(&dev, &start_lbn, &count) != 0) return 1;
|
||||
if (artemis_sig_check(&dev, &sig) != ARTEMIS_SIG_BLANK) {
|
||||
fprintf(stderr, "mkartemis: the partition is not blank -- not formatted\n");
|
||||
@@ -221,7 +236,8 @@ int main(int argc, char **argv)
|
||||
printf("mkartemis: formatted %u blocks, STFR v2, signature stamped, read back ok\n", r.blocks);
|
||||
} else {
|
||||
if (check_volume(&dev, &count, &sig) != 0) return 1;
|
||||
printf("mkartemis: STFR v2, %u user blocks, signature ok, disk_uuid ", count);
|
||||
printf("mkartemis: STFR v2, %u user blocks, bam %u devblocks, signature ok, disk_uuid ",
|
||||
count, g_bam_devblocks);
|
||||
for (i = 0; i < 16; i++) printf("%02x", sig.disk_uuid[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -591,6 +591,18 @@ int blk_subsys_add_raw_device(uint8_t *buf, uint32_t nblocks);
|
||||
* by the disk's owner before any write to that slot will succeed. */
|
||||
int blk_subsys_confirm_format(uint32_t lbn);
|
||||
|
||||
/* blk_volume_compute_totals - a volume's tracked/total block counts from its
|
||||
* total_devblocks, bam_devblocks, reloc_devblocks and meta_fence_blocks, as a
|
||||
* fresh format computes them. For a volume grown to fill a larger partition
|
||||
* (the v4 stick, plan 2026-10-29-stick-5, Task 2). */
|
||||
void blk_volume_compute_totals(blk_volume_meta_t *m);
|
||||
|
||||
/* blk_subsys_set_format_bam_for - size the BAM of the next fresh format for a
|
||||
* volume of `total_devblocks` 4 KiB devblocks, when that is more than the
|
||||
* disk's own: the volume can later grow that far with no BAM of its own to
|
||||
* move (mkartemis --bam-for). 0, the default, sizes it for the disk. */
|
||||
void blk_subsys_set_format_bam_for(uint64_t total_devblocks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -386,6 +386,20 @@ static void compute_totals_from_B(blk_volume_meta_t *m) {
|
||||
* blk_compute_fresh_geometry()). */
|
||||
}
|
||||
|
||||
/* compute_totals_from_B, for a volume grown on its disk (the v4 stick:
|
||||
* docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md, Task 2). */
|
||||
void blk_volume_compute_totals(blk_volume_meta_t *m) {
|
||||
if (m) compute_totals_from_B(m);
|
||||
}
|
||||
|
||||
/* The BAM a fresh format sizes: for this many devblocks when it is more than
|
||||
* the disk's own (0: the disk's). Only mkartemis sets it (--bam-for). */
|
||||
static uint64_t g_format_bam_for;
|
||||
|
||||
void blk_subsys_set_format_bam_for(uint64_t total_devblocks) {
|
||||
g_format_bam_for = total_devblocks;
|
||||
}
|
||||
|
||||
/* ===== physical BAM I/O (sync to/from slot->bam[]) ===== */
|
||||
|
||||
/*
|
||||
@@ -530,7 +544,8 @@ static void blk_compute_fresh_geometry(blk_dev_slot_t *slot) {
|
||||
strncpy(slot->vol_meta.label, "StarForth Volume", sizeof(slot->vol_meta.label) - 1);
|
||||
slot->vol_meta.total_devblocks = (uint64_t) udiv_floor(slot->total_blkio_blocks_1k, 4);
|
||||
slot->vol_meta.bam_start = 1;
|
||||
slot->vol_meta.bam_devblocks = choose_B(slot->vol_meta.total_devblocks);
|
||||
slot->vol_meta.bam_devblocks = choose_B(g_format_bam_for > slot->vol_meta.total_devblocks
|
||||
? g_format_bam_for : slot->vol_meta.total_devblocks);
|
||||
slot->vol_meta.reloc_start = slot->vol_meta.bam_start + slot->vol_meta.bam_devblocks;
|
||||
/* One devblock (4 KiB): a 4-byte count prefix + up to BLK_RELOC_MAX_ENTRIES
|
||||
* 8-byte {home_lbn, actual_lbn} pairs -- see this file's own doc comment
|
||||
|
||||
Reference in New Issue
Block a user