SchOS/.claude/memory/schunix-crash-screen.md
Nexoniarz a1c965da1e include: one folder per subsystem, and includes that name it
Sixty-five headers sat side by side in include/, so `#include "irq.h"`
said nothing about where irq.h was or what it belonged to, and errno.h,
stat.h and fcntl.h at the top shadowed the system's for any host tool
built with -I./include. They are in folders now -- arch/ core/ fs/
dev/ gfx/ net/ uapi/ (and ldls/ for the Linux driver layer) -- and
every include names the folder, as Linux's do: "core/proc.h".

Done mechanically and checked the hard way: the kernel built from this
tree disassembles identically to the one built from the tree before
it. The full image boots, and userland is the same set of programs.
Paths in docs and comments follow; docs/guides/layout.md has a table
of what is where, and tools/fix-includes.py rewrites old-style
includes from the folders in the tree, for code written before this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
2026-10-23 15:05:12 +02:00

81 lines
4 KiB
Markdown

---
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`.