starkernel: item 3.2 -- Stadium boot-time allocation

Punch list §25 item 3.2 complete.

stadium_boot_init() (src/starkernel/vm/stadium.c) sizes the global
cell array at boot from a real memory-budget query rather than a
hardcoded count: pmm_get_stats().free_bytes at the point of
allocation, times the new STADIUM_MEMORY_PERCENT Kconfig symbol
(default 1%), rounded down to whole 64-byte cells. Matches §17.6's
position (b) literally. Also allocates the header/continuation
discriminator bitmap item 3.1 declared but did not allocate. Both are
kmalloc'd and explicitly zero-filled (kmalloc does not zero).

Called from kernel_main.c immediately before sk_vm_bootstrap_parity(),
i.e. before any VM exists (§6). Failure is soft -- logs and continues,
does not halt boot -- matching the existing precedent one line below
it (VM bootstrap parity failure does the same).

Added a "Stadium: N cells (M KB)" boot console line at the allocation
site so the acceptance logs are evidence the array was actually
allocated, not just that the kernel still boots -- the same blind spot
item 3.1's uncompiled-header gap exposed.

Verified: three-architecture boot (amd64, aarch64, riscv64), all
reaching ok> with identical dict_hash=0x3d4e1daf289da94f matching the
item-3.1 baseline, and the Stadium boot line confirmed present in all
three serial logs (amd64: 74234 cells/4639 KB, aarch64: 161329
cells/10083 KB, riscv64: 76122 cells/4757 KB).

Not built here, reported per §25.0 rule 3: per-VM free lists (§22.3)
-- granted when Hera assigns quota, not this item's scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-04 16:48:13 -04:00
co-authored by Claude Sonnet 5
parent 1b2f0677de
commit eb0fd4fffa
14 changed files with 31496 additions and 9 deletions
+6
View File
@@ -52,6 +52,7 @@ EFI_RUNTIME_SERVICES *g_sk_runtime_services = NULL;
#ifdef STARFORTH_ENABLE_VM
#include "starkernel/vm/bootstrap/sk_vm_bootstrap.h"
#include "starkernel/vm/parity.h"
#include "starkernel/vm/stadium.h"
#include "starkernel/capsule_generated.h"
#include "starkernel/capsule_loader.h"
#include "starkernel/capsule_birth.h" /* capsule_birth_mama, capsule_find_mama_init */
@@ -478,6 +479,11 @@ static void kernel_main_deep(BootInfo *boot_info) {
console_println("Boot successful!\n");
#ifdef STARFORTH_ENABLE_VM
/* Stadium: boot-time allocation (FABRIC.md item 3.2), before any VM
* exists (§6). Soft failure -- nothing downstream consumes the Stadium
* yet, so a failed allocation logs and boot continues. */
(void)stadium_boot_init();
/* M7: VM Bootstrap and Parity Validation */
console_println("VM: bootstrap parity...");
ParityPacket parity_pkt;
+96 -6
View File
@@ -22,12 +22,102 @@
*/
/**
* stadium.c - Translation unit for the Stadium cell definitions (item 3.1).
* stadium.c - The Stadium cell definitions (item 3.1) and boot-time
* allocation (item 3.2).
*
* Exists so stadium.h's compile-time size assertions are actually compiled
* on all three architectures, not merely included by something that never
* builds. No behavior yet -- item 3.2 onward adds the array, dispatch, and
* ranking.
* Also the translation unit that makes stadium.h's compile-time assertions
* actually get compiled on all three architectures, not merely included by
* something that never builds.
*/
#include "starkernel/vm/stadium.h"
#include "starkernel/vm/stadium.h"
#ifdef __STARKERNEL__
#include "starkernel/kmalloc.h"
#include "starkernel/pmm.h"
#include "starkernel/console.h"
static StadiumCell *stadium_cell_array = (StadiumCell *)0;
static uint8_t *stadium_bitmap = (uint8_t *)0;
static size_t stadium_ncells = 0;
static int stadium_initialized = 0;
/* Freestanding: no libc printf. Prints an unsigned decimal, no leading zeros. */
static void console_put_u64(uint64_t v) {
char buf[21];
int i = 20;
buf[20] = '\0';
if (v == 0) {
console_puts("0");
return;
}
while (v > 0 && i > 0) {
buf[--i] = (char)('0' + (v % 10));
v /= 10;
}
console_puts(&buf[i]);
}
int stadium_boot_init(void) {
pmm_stats_t pmm = pmm_get_stats();
uint64_t budget_bytes = (pmm.free_bytes * (uint64_t)STADIUM_MEMORY_PERCENT) / 100u;
size_t ncells = (size_t)(budget_bytes / STADIUM_CELL_BYTES);
size_t bitmap_bytes = (ncells + 7u) / 8u;
if (ncells == 0) {
console_println("Stadium: boot-time allocation skipped (0 cells from memory budget)");
return -1;
}
StadiumCell *cells = (StadiumCell *)kmalloc(ncells * STADIUM_CELL_BYTES);
uint8_t *bitmap = (uint8_t *)kmalloc(bitmap_bytes);
if (!cells || !bitmap) {
console_println("Stadium: kmalloc failed for boot-time allocation");
if (cells) kfree(cells);
if (bitmap) kfree(bitmap);
return -1;
}
{
uint8_t *raw = (uint8_t *)cells;
size_t n = ncells * STADIUM_CELL_BYTES;
size_t i;
for (i = 0; i < n; i++) raw[i] = 0;
}
{
size_t i;
for (i = 0; i < bitmap_bytes; i++) bitmap[i] = 0;
}
stadium_cell_array = cells;
stadium_bitmap = bitmap;
stadium_ncells = ncells;
stadium_initialized = 1;
console_puts("Stadium: ");
console_put_u64((uint64_t)ncells);
console_puts(" cells (");
console_put_u64((uint64_t)(ncells * STADIUM_CELL_BYTES) / 1024u);
console_println(" KB)");
return 0;
}
int stadium_is_initialized(void) {
return stadium_initialized;
}
size_t stadium_cell_count(void) {
return stadium_ncells;
}
StadiumCell *stadium_cells(void) {
return stadium_cell_array;
}
uint8_t *stadium_header_bitmap(void) {
return stadium_bitmap;
}
#endif /* __STARKERNEL__ */