SchOS/.claude/memory/schunix-boot-splash-logo.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

61 lines
3.6 KiB
Markdown

---
name: schunix-boot-splash-logo
description: "The boot logo pipeline, why the loader draws it rather than the kernel, and the STAGE2_SECTORS trap that consolidating it exposed."
metadata:
node_type: memory
type: project
originSessionId: 9d8a2aef-bcf0-47a0-96c6-f706efab4a95
modified: 2026-08-08T12:04:49.027Z
---
The boot splash shows the `Assets/Schunix Small Logo.png` mark (an SX monogram in
a ring) above the `S C H U N I X` wordmark and its accent rule, all centred as
one group. Verified rendering correctly on 2026-08-08.
**The logo is drawn by the bootloader, not the kernel.** This is the
counter-intuitive part and it is a timing fact, not a preference: the kernel does
not reach `vga_init()` until roughly the last 300ms of a ~2.8s boot, so a
kernel-drawn logo appeared for about one frame before `console_takeover()` wiped
it. Drawn from `splash()` in `boot/stage2main.c` it is up for the whole boot.
`kernel/dev/vga.c` keeps the same drawing code against the same mask
(`vga_draw_logo`, `vga_logo_centered`) for things that want the mark *after*
boot — the crash screen, eventually `schinit`. Don't "fix" the duplication by
deleting the loader's copy.
**Pipeline:** `tools/mklogo.py` (host Python, has its own PNG inflate +
un-filter) crops to the mark, box-downscales, normalises to full strength, packs
to a 4-bit coverage mask, and writes `include/gfx/logo.h`. Run `make logo` — it is
*not* a build dependency, and `include/gfx/logo.h` is committed, on the same
reasoning as `include/gfx/font.h`. The mask is coverage, not colour, so the palette
stays in [[schunix-console-tty]]'s `include/gfx/theme.h`; the loader composites it in
`SCH_FG` because the source art is a silver gradient and the accent is reserved
for the one rule. 4 bits rather than 8 because the header is included by the
*bootloader*, where size is a boot constraint.
**`STAGE2_SECTORS` was encoded in five places, not the three `docs/guides/layout.md`
claimed.** Raising it 24 → 48 to fit the 8 KiB mask proved it: the `dd seek=25`
offset stayed behind and the kernel got written straight over stage2's tail.
The five were `boot/bootasm.S`, `boot/stage2main.c`, the `dd seek=`, and *twice*
inside `tools/mkiso.sh` (its size assertion and `-boot-load-size`). It now lives
only in the root Makefile, which passes `-DSTAGE2_SECTORS` and exports it to
mkiso; the `#define`s left in the boot sources are `#ifndef` fallbacks. Hard
ceiling is 65 sectors — stage2 loads at `0x7E00` and must not reach the
multiboot kernel-search buffer at `0x10000` — and `stage2main.c` now
static-asserts that. See also [[schunix-iso-boot]].
**`tools/splashshot.ps1`** captures a burst of QEMU screendumps across early
boot and reports each frame's distinct-colour count, because the splash window
is too short to hit with a single guessed delay. It uses `-snapshot` plus
`file.locking=off` so it runs while an interactive QEMU has the images open —
booting from copies also works but means duplicating all 153 MB of
`build/fs.img` per run. Colour counts are the
assertion: ~2 means text console or blank, 18 means the 4bpp logo is up. If it
ever reads 156 again, something is drawing an 8-bit mask.
**Two traps, both hit while doing this:**
- `$(shell expr $(N) \* 512)` in a Makefile does not work — make passes the
backslash through, sh globs the `*`, and expr receives a directory listing.
Make silently carries on with nonsense. Use `$$(( ))` in the recipe.
- `make iso` was failing when this was written, for unrelated reasons since
fixed — see [[schunix-ramdisk-root-sizing]]. `-boot-load-size 49` is now
verified: the ISO boots from optical media only.