--- name: schunix-crash-screen description: "PSOGM crash screen lives in kernel/core/panic.c; test it with `echo c > /proc/sysrq` and tools/crashshot.ps1" metadata: node_type: memory type: project originSessionId: a665e14b-86bd-4b41-a228-51377f3e9225 modified: 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]]. ## 2026-09-21: the face is gone, and a bug it exposed PSOGM draws **Shift**, the system logo, where the Guru face used to be — `gfx_draw_logo()` from `include/gfx/logo.h`, the same mask the loader splash and the boot console use, at its native 128 px. `draw_guru()` and its geometry constants are deleted; so are `docs/branding/guru.svg` and the mascot brief. The *name* "Purple Screen of Guru Meditation" stays — that is the Amiga nod, which was always a separate thing from the mark. Taking the screenshot to check it caught a real regression from the TTF console work: **`gfx_draw_char()` still indexed the 8x16 bitmap with the TrueType cell height.** `font_data` has 16 rows per glyph and `CHAR_HEIGHT` became ~21, so every line of PSOGM drew five rows of the *next character's* bitmap underneath itself — it looked like each line had been printed twice. The grid path (`gfx_draw_cell`) had been updated; this one had not, because nothing routine draws pixel-positioned text. Both now go through one `draw_glyph_px()`, and the bitmap's own geometry is spelled `BITMAP_W/H` so it cannot be confused with a cell size again. **A crash screen is only checked by looking at it**, and nothing else in the system exercises `gfx_text_at`. Screenshot it after any font or console change: `echo c > /proc/sysrq`, then a QEMU monitor `screendump`.