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
4 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 |
|
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.
isqrtin 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_charfills the background of every glyph withvga_bg. Drawing panel text without settingvga_set_bg(PSOGM_PANEL)first puts every line in a cream-coloured box. -
cprintfwrites to the framebuffer as well as the serial line, so the serial report scrolls straight over the panel.cons_panic_mode()setscons_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.