feat(kernel): the fixed screen -- with a real Zuse, the system stick alone can only mint a replacement (#92, 5.3-5.5) [skip ci]

The four lines on the screen and serial while the proxy is recognised and her stick is not here; R runs sk_v4_mint_zuse(), every other key is dropped. Her stick pulled: the screen again. The system stick pulled while hers is in: hers let go first (the block chain's tail), remembered for the system stick's return. Builds on three ISAs; fallback running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2
This commit is contained in:
Claude
2026-11-10 06:34:56 +00:00
parent 46baa3f0d0
commit 933f50fa18
2 changed files with 77 additions and 12 deletions
+74 -9
View File
@@ -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) */
}