diff --git a/docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md b/docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md index 766c1534..20de255c 100644 --- a/docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md +++ b/docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md @@ -364,9 +364,9 @@ Tasks 1-3 accepted and merged (#159, master 594d2f93); #155 merged with them. **Task 5, the fixed screen** (increments, as Task 4's): - [x] 5.1 the first failing test: mode `fallback` (a mint, then the data stick booted alone: the four lines, no prompt, keys dropped; her stick added: the prompt; pulled: the screen again; R with no stick: the plug-in line, any key stops it) - [x] 5.2 run `fallback` before any kernel change: FAIL -- no fixed screen, R does nothing (logs/20261110-062351, -062543); her stick added, the prompt, typed keys dropped, the session ended on its pull all PASS already -- [ ] 5.3 the fixed screen in `sk_v4_identity_wait()`: shown while `g_proxy_fallback`; R runs `sk_v4_mint_zuse()`; every other key dropped -- [ ] 5.4 her stick pulled: the fixed screen again (not headless) -- [ ] 5.5 the system stick pulled while hers is in: hers let go first (the chain's tail) +- [~] 5.3 the fixed screen in `sk_v4_identity_wait()`: shown while `g_proxy_fallback`; R runs `sk_v4_mint_zuse()`; every other key dropped +- [~] 5.4 her stick pulled: the fixed screen again (not headless) +- [~] 5.5 the system stick pulled while hers is in: hers let go first (the chain's tail). 5.3-5.5 written in `sk_v4_identity.c` (`sk_v4_fixed_screen`, `sk_v4_session_end`, `g_real_drive`); build on three ISAs; `fallback` running (build/t5/fallback-53.txt) - [ ] 5.6 the other sessions: `replace` (R, a new stick, the old one refused), `mint_fail` (blkdebug write errors), `real_pull`, `system_pull_real` - [ ] 5.7 regressions, full acceptance, FABRIC entry, commit; then the SER5 bench steps in `boards/BRINGUP.md` (Task 5 step 6) diff --git a/kernel/src/v4/sk_v4_identity.c b/kernel/src/v4/sk_v4_identity.c index 6ea0f5d8..63e3553a 100644 --- a/kernel/src/v4/sk_v4_identity.c +++ b/kernel/src/v4/sk_v4_identity.c @@ -49,6 +49,7 @@ #include "starkernel/gpt.h" #include "starkernel/v4/sk_v4_marker.h" #include "starkernel/v4/sk_v4_grow.h" +#include "starkernel/v4/sk_v4_mint.h" #ifdef ARCH_AMD64 #include "starkernel/ioapic.h" #include "starkernel/i8042.h" @@ -110,6 +111,8 @@ static sk_v4_drive_t *g_spare; * Artemis) and arrived before the system stick: checked once it is in * (plan 2026-10-29-stick-5, Review Focus 1) */ static sk_v4_drive_t *g_pending_real; +/* the real Zuse's stick, while it is attached */ +static sk_v4_drive_t *g_real_drive; static const BootDisk *g_boot_disk; /* the loader's: the disk it booted from */ static int g_stick_in; /* a stick's Artemis partition is attached */ @@ -300,6 +303,7 @@ static int sk_v4_real_zuse_arrived(sk_v4_drive_t *d, unsigned nparts) return 1; } d->used = &d->part; + g_real_drive = d; g_proxy_fallback = 0; sk_v4_login(&d->part, seed, pubkey, "Zuse: identity confirmed from attached thumbdrive"); memset(seed, 0, sizeof seed); @@ -426,10 +430,38 @@ static int sk_v4_drive_arrived(sk_v4_drive_t *d) /* A drive that has left: its identity partition is let go, then its Artemis * partition -- in that order, because blk_subsys_detach_device() removes * only the chain's tail, and the identity partition was attached last. */ +/* Zuse's session ends: nothing of it stays on the screen */ +static void sk_v4_session_end(void) +{ + g_zuse_session = 0; + g_zuse_dev = (struct blkio_dev *)0; +#if !EMERGENCY_CONSOLE_ENABLED + console_fb_clear(); + console_fb_mirror(0); +#endif + console_println("Zuse: session ended -- reattach to re-authenticate"); +} + static void sk_v4_drive_left(sk_v4_drive_t *d) { blkio_dev_t *dev = d->used; + /* the system stick going while the real Zuse's is in: hers is the block + * chain's tail (blk_subsys_detach_device removes only the tail), so it is + * let go first -- remembered, to be checked again when the system stick + * is back (plan 2026-10-29-stick-5, Task 5, system_pull_real) */ + if (d->art_used && g_real_drive && g_real_drive != d) { + sk_v4_drive_t *r = g_real_drive; + g_real_drive = (sk_v4_drive_t *)0; + if (r->used) { + if (r->used == g_zuse_dev) sk_v4_session_end(); + blk_subsys_detach_device(r->used); + r->used = (blkio_dev_t *)0; + } + g_pending_real = r; + } + if (d == g_real_drive) g_real_drive = (sk_v4_drive_t *)0; + if (d == g_offered) g_offered = (sk_v4_drive_t *)0; /* the offered stick, pulled */ if (d == g_spare) g_spare = (sk_v4_drive_t *)0; if (d == g_pending_real) g_pending_real = (sk_v4_drive_t *)0; @@ -442,20 +474,23 @@ static void sk_v4_drive_left(sk_v4_drive_t *d) blk_subsys_detach_device(d->art_used); d->art_used = (blkio_dev_t *)0; g_stick_in = 0; - g_proxy_fallback = 0; + if (g_proxy_fallback) { /* the fixed screen goes with the system stick */ + g_proxy_fallback = 0; +#if !EMERGENCY_CONSOLE_ENABLED + console_fb_clear(); + console_fb_mirror(0); +#endif + } memset(&g_marker, 0, sizeof(g_marker)); } if (!dev || dev != g_zuse_dev) return; - g_zuse_session = 0; - g_zuse_dev = (struct blkio_dev *)0; /* nothing of her session is left on the screen; it is dark again -- * except in a build with EMERGENCY_CONSOLE_ENABLED, whose console needs * no login and goes on running (the stick's increment 1 final review) */ -#if !EMERGENCY_CONSOLE_ENABLED - console_fb_clear(); - console_fb_mirror(0); -#endif - console_println("Zuse: session ended -- reattach to re-authenticate"); + sk_v4_session_end(); + /* the real Zuse's stick pulled, the system stick still in: the fixed + * screen comes back (STICK.md 6a), not a dark one */ + if (g_stick_in && g_marker.present && g_marker.has_real) g_proxy_fallback = 1; } /* One idle beat: the xHCI event ring, then every drive that has arrived or @@ -581,10 +616,40 @@ static void sk_v4_discard_input(void) sk_input_drop(); } +/* The fixed screen (docs/v4.0.0/STICK.md 6a; plan 2026-10-29-stick-5, Task + * 5): the system stick's proxy recognised, a real Zuse in the marker, and + * her stick not here. On the screen and on serial. */ +static void sk_v4_fixed_screen(void) +{ + console_fb_clear(); + console_fb_mirror(1); + console_fb_enable_ttf(); + console_println("Zuse's stick is not here."); + console_println("Plug it in to log in."); + console_println("Or plug in another stick and press R to mint a replacement"); + console_println("-- the old Zuse stick will stop working."); +} + void sk_v4_identity_wait(void) { + int shown = 0; + while (!g_zuse_session) { - sk_v4_discard_input(); + if (g_proxy_fallback) { + /* the proxy can only mint a replacement: R does it, every other + * key is read and dropped */ + int c; + if (!shown) { sk_v4_fixed_screen(); shown = 1; } + c = sk_input_getc(); + if (c == 'R' || c == 'r') { + (void)sk_v4_mint_zuse(); + shown = 0; /* stopped or failed: the screen again */ + continue; + } + } else { + shown = 0; + sk_v4_discard_input(); + } sk_v4_identity_beat(); arch_halt(); /* headless, until Zuse: wait for the next tick, not a spin (#151) */ }