starkernel: Phase 0 acceptance -- three-arch boot + reproducibility (item 0.10)
Adds a one-time boot diagnostic in kernel_main.c, right before sk_repl() is entered: bounded wait for 3 real heartbeat ticks, then prints tick count, TIME-TRUST, and variance. Needed because printing immediately after apic_timer_start() (as first tried) measured 1 tick on amd64 and 0 on riscv64 -- not evidence the heartbeat doesn't work, just that almost no wall time elapses between arming the timer and that point in boot; report it honestly rather than let it stand as a false negative. Verified this session (logs/20260804-001727, -001805, -001850, -001948, -002021): - All three architectures boot to ok>. - Tick count non-zero: amd64 4, riscv64 3, aarch64 3. - riscv64: trust=Q48_ONE exactly, variance=0 -- architecturally invariant counter, as designed. - amd64: dict_hash=0x3d4e1daf289da94f, identical to the pre-item-0.8 baseline (logs/20260803-231322) -- unchanged output, satisfying the GAP-A1 control. - Two consecutive amd64 boots produced the identical dict hash -- reproducible, no wall-clock leakage into patron state. Phase 0 (Substrate) is complete. Punch list §25 item 0.10 complete. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
bfc0cb9bfd
commit
024f8a84b5
@@ -662,6 +662,52 @@ static void kernel_main_deep(BootInfo *boot_info) {
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
/* Phase 0 acceptance (§25.1 item 0.10): "tick count non-zero" has to be
|
||||
* true, not merely likely -- the timer was just armed above, so with no
|
||||
* wait here the count depends on how much boot work happened to run
|
||||
* concurrently with interrupts enabled, which measured 1 tick on amd64
|
||||
* and 0 on riscv64 in practice. Bounded busy-wait for a few real ticks
|
||||
* (not a virtual-tick construct; §16.4/§18.5 govern patron state, not
|
||||
* this one-time boot diagnostic) rather than reporting whatever count
|
||||
* happened to land. */
|
||||
{
|
||||
uint64_t wait_start = heartbeat_ticks();
|
||||
uint64_t spins = 0;
|
||||
while (heartbeat_ticks() - wait_start < 3 && spins < 100000000ULL) {
|
||||
arch_relax();
|
||||
spins++;
|
||||
}
|
||||
}
|
||||
console_puts("Heartbeat: ");
|
||||
{
|
||||
char buf[24]; uint64_t v = heartbeat_ticks(); int i = 0, j = 0; char t[24];
|
||||
if (v == 0) buf[i++] = '0';
|
||||
else { while (v > 0) { t[j++] = (char)('0' + (v % 10)); v /= 10; } while (j > 0) buf[i++] = t[--j]; }
|
||||
buf[i] = '\0';
|
||||
console_puts(buf);
|
||||
}
|
||||
console_puts(" ticks, trust=0x");
|
||||
{
|
||||
char buf[9]; uint32_t v = (uint32_t)heartbeat_trust();
|
||||
for (int k = 7; k >= 0; k--) {
|
||||
int nib = (int)((v >> (k * 4)) & 0xF);
|
||||
buf[7 - k] = (char)(nib < 10 ? '0' + nib : 'a' + nib - 10);
|
||||
}
|
||||
buf[8] = '\0';
|
||||
console_puts(buf);
|
||||
}
|
||||
console_puts(", variance=0x");
|
||||
{
|
||||
char buf[9]; uint32_t v = (uint32_t)heartbeat_state()->variance;
|
||||
for (int k = 7; k >= 0; k--) {
|
||||
int nib = (int)((v >> (k * 4)) & 0xF);
|
||||
buf[7 - k] = (char)(nib < 10 ? '0' + nib : 'a' + nib - 10);
|
||||
}
|
||||
buf[8] = '\0';
|
||||
console_puts(buf);
|
||||
}
|
||||
console_println("");
|
||||
|
||||
sk_repl(mama);
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user