starkernel: land console_fb_init() reorder (FABRIC.md 4.4g decided)

Moves the console_fb_init() call in kernel_main.c from after
capsule_birth_mama() to before it, so the fleet-birth/self-test
transcript (Hermes x2, Artemis births, Stadium self-tests -- currently
serial-only) is also framebuffer-visible, not just the small post-birth
tail.

4.5f's -O2 experiment already showed this doesn't hang under
optimization, just costs roughly 12x more boot-time heartbeat ticks
(one-shot, paid only during fleet birth, never repeated at runtime).
Captain Bob's call: worth it, since the serial log was never the
problem -- this is about the same transcript also reaching a real
screen.

Three-arch verified: amd64/aarch64/riscv64 all reach ok>, POST
Failed: 0, identical dict-hashes across all three. amd64 screendump
confirms the framebuffer now carries the full transcript.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-11 17:18:58 -04:00
co-authored by Claude Sonnet 5
parent 9b117c787f
commit f33353430f
13 changed files with 54909 additions and 131 deletions
+23 -25
View File
@@ -593,6 +593,23 @@ static void kernel_main_deep(BootInfo *boot_info) {
* sequence parity across all three architectures is unaffected. */
(void)virtio_input_find_keyboard();
/* FABRIC.md item 4.4g (decided 2026-08-11): console_fb_init() moved here,
* before capsule_birth_mama(), so the fleet-birth/self-test transcript is
* framebuffer-visible too, not just the small post-birth tail. Costs
* roughly 12x more boot-time heartbeat ticks (one-shot, at boot only --
* see 4.5f) in exchange for the fuller on-screen record; Captain Bob's
* call, made after 4.5f's -O2 experiment showed the earlier indefinite
* -O0 stall was a compiler-optimization problem, not a correctness one. */
if (boot_info->framebuffer.base != NULL && boot_info->framebuffer.size > 0) {
FbPixelFormat fb_fmt;
switch (boot_info->framebuffer.pixel_format) {
case (UINT32)PixelRedGreenBlueReserved8BitPerColor: fb_fmt = FB_PIXEL_RGBX32; break;
case (UINT32)PixelBlueGreenRedReserved8BitPerColor: fb_fmt = FB_PIXEL_BGRX32; break;
default: fb_fmt = FB_PIXEL_BGRX32; break;
}
console_fb_init(&boot_info->framebuffer, fb_fmt);
}
/* Copy capsule directory header to heap (has pointer field needing update) */
CapsuleDirHeader *live_dir = (CapsuleDirHeader *)kmalloc(sizeof(CapsuleDirHeader));
if (!live_dir) {
@@ -826,31 +843,12 @@ static void kernel_main_deep(BootInfo *boot_info) {
if (mama->halted) goto idle;
#endif
/*
* FABRIC.md item 4.4c (2026-08-11): console_fb_init() wires the
* framebuffer AND turns on vt100_init(), so serial and framebuffer
* consoles carry identical output from here on -- Captain Bob's stated
* end goal. Previously only raw fb_init() ran and console.c/vt100.c's
* framebuffer path was deliberately skipped ("superseded by the Console
* drawing-fabric redesign"); that left vt100_putc() permanently
* uninitialized and no console output ever reached the screen.
* console_fb_init() calls fb_init() internally, so this replaces the
* old call, not adds to it.
*
* fb_draw_orientation_test() (item 4.3.1's one-time diagnostic, already
* [x] done) removed 2026-08-11 -- its corner test blocks were only
* needed to verify the raw GOP framebuffer wiring once; now that vt100
* is live, they just obscure real console output in every screendump.
*/
if (boot_info->framebuffer.base != NULL && boot_info->framebuffer.size > 0) {
FbPixelFormat fb_fmt;
switch (boot_info->framebuffer.pixel_format) {
case (UINT32)PixelRedGreenBlueReserved8BitPerColor: fb_fmt = FB_PIXEL_RGBX32; break;
case (UINT32)PixelBlueGreenRedReserved8BitPerColor: fb_fmt = FB_PIXEL_BGRX32; break;
default: fb_fmt = FB_PIXEL_BGRX32; break;
}
console_fb_init(&boot_info->framebuffer, fb_fmt);
}
/* FABRIC.md item 4.4g (decided 2026-08-11): console_fb_init() call site
* moved earlier in this function, before capsule_birth_mama() -- see that
* call site's comment. This used to be here (item 4.4c, 2026-08-11: wires
* the framebuffer AND turns on vt100_init(), so serial and framebuffer
* consoles carry identical output; console_fb_init() calls fb_init()
* internally, replacing the old raw fb_init()-only call). */
/* Clear reboot-tries counter: we reached the REPL cleanly */
if (g_sk_runtime_services) {