SchOS/.claude/memory/schunix-crash-screen.md
Nexoniarz 3182da3965 Carry project memory in the repo, with tools/memory-sync.sh
Claude Code keeps per-project memory at <home>/.claude/projects/<key>/,
where <key> is the project's absolute path with every separator and the
drive colon turned into a dash. That makes it both rename-fragile and
machine-specific, and this project has hit each of those once:

  - D:\DEV\Schunix -> D:\DEV\SchOS changed the key, and 43 memories were
    invisible until moved across by hand.
  - Development happens from Windows and from Linux, and each looks in a
    different place for the same checkout.

Committing .claude/memory/ fixes both -- git carries it across renames
and between hosts -- and `import` puts it wherever the local machine
expects. .claude/settings.local.json stays ignored: those are per-machine
permissions.

The colon maps to a dash rather than being dropped. Deleting it gives
D-DEV-SchOS, which matches nothing and silently finds zero memories; that
was the first attempt. On Git Bash the key comes from `cygpath -w`,
because Claude Code is a Windows program and sees D:\DEV\SchOS, not
/d/DEV/SchOS.
2026-08-09 14:27:22 +02:00

2.6 KiB

name description metadata
schunix-crash-screen PSOGM crash screen lives in kernel/core/panic.c; test it with `echo c > /proc/sysrq` and tools/crashshot.ps1
node_type type originSessionId modified
memory project a665e14b-86bd-4b41-a228-51377f3e9225 2026-08-03T15:09:42.189Z

The crash screen is kernel/core/panic.c (rewritten 2026-08-03; it used to live inside console.c). PSOGM — Purple Screen of Guru Meditation. Solid purple, big white :( drawn from primitives, Windows-style left-aligned headline and field table, then a raw call-chain dump. Nexoniarz picked this after a first attempt that dimmed the desktop and floated a dark panel with a cartoon emoji over it — the emoji and the muted palette read as out of place; the name says purple screen, so it is one.

A "Stop code" field is derived from the panic message (uppercased up to the first colon: "sysrq: crash requested" → SYSRQ), so no call site has to supply one.

To see it, crash on purpose:

echo c > /proc/sysrq          # from inside Schunix

To photograph it: pwsh -File tools/crashshot.ps1 (or make crashshot) after make ramroot. It boots, fills the screen with real output, crashes, and pulls a PPM out through QEMU's monitor on TCP 55555. Convert with convert build/crashscreen.ppm build/crashscreen.png — ImageMagick is in the WSL Fedora box as convert, not magick.

Why the trigger exists at all: the crash screen is the one part of the system you cannot look at by using the system, so without a deliberate trigger it is only ever seen when something is already wrong, and it quietly rots.

Three things that will bite anyone editing it:

  • There is no libm. isqrt in panic.c uses Newton's method iterated while the estimate decreases; the obvious "stop when it stops changing" version does not terminate, because on a non-square it settles into a two-cycle (isqrt(3) alternates 1, 2, 1, 2...). That shipped once and hung the panic handler with the screen half drawn — a hang with no way to find out why.

  • vga_draw_char fills the background of every glyph with vga_bg. Drawing panel text without setting vga_set_bg(PSOGM_PANEL) first puts every line in a cream-coloured box.

  • cprintf writes to the framebuffer as well as the serial line, so the serial report scrolls straight over the panel. cons_panic_mode() sets cons_serial_only, which is what keeps the two apart — paint order alone does not.

The serial copy is the one that survives, and it is what tools/bootcheck.ps1 reads. It is also all you get when the panic happens before there is a framebuffer. See schunix-verify-by-driving-shell.