GMMOS: the Guru Meditation Micro OS, alive under the PSOGM

A panic no longer ends in a picture. The report is drawn as before, and
then GMMOS runs under it: the real kernel stays dead -- the other
processors are halted, and nothing of it is called that locks, sleeps,
allocates or waits for an interrupt -- and GMMOS keeps its own clock
(the TSC), its own keyboard (micro drivers, polled), and the screen.

On the report: a live status line counting down the three-minute
power-off, which any key cancels, and the keys.

  Space  the last 300 lines of this boot's log as QR codes, a page per
         symbol, numbered; + and - trade module size for capacity
  L      the log on screen, scrolled
  T      a terminal: why, log, grep, ps, cpus, pci, mem (page tables
         walked first, so a bad address cannot fault), uptime, restart,
         poweroff
  R R    restart; P P power off -- twice, so a stray key does neither

The first micro driver is PS/2, polled: kbd.c with everything but the
keys taken out. The probe asks the keyboard to echo, so a controller
with nothing behind it is not offered as one. Polling also sidesteps the
IRQ 1 polarity quirk, which is about interrupt routing.

A panic inside GMMOS (or a second one in the report) is reported and
then only blinks; it does not re-enter GMMOS.

Checked under QEMU: every screen; two QR pages read off a screenshot
with zbar decode to the log text exactly; restart reboots; left alone it
still powers off at three minutes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-25 01:11:04 +02:00
commit cb9b06d46f
9 changed files with 1317 additions and 7 deletions

View file

@ -267,6 +267,17 @@ klog_len(void)
}
uint64 klog_prev_bytes(void) { return prev_bytes; }
// How much of what the ring holds this boot wrote: the tail of it, since the
// ring is read oldest first. GMMOS shows this boot's log, not the last one's.
uint64
klog_boot_bytes(void)
{
if (!klog)
return 0;
uint64 n = klog->head - klog->mark;
return n < klog_len() ? n : klog_len();
}
int klog_recovered(void) { return recovered; }
// Read at a byte offset into the log, where 0 is the oldest byte still held.