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
This commit is contained in:
parent
0e39e711f1
commit
a1c965da1e
267 changed files with 1560 additions and 1440 deletions
|
|
@ -19,7 +19,7 @@
|
|||
- [SchFS phase 2: real mount](schfs-phase2-mount.md) — mkschfs writes images, the kernel mounts them read-only; `make schfs-check`, plus four traps worth remembering.
|
||||
- [SchFS phase 3: writes](schfs-phase3-writes.md) — full write API, free map derived not stored, and `mount -t schfs` works; the VFS now dispatches through `struct fs_ops`.
|
||||
- [DIRSIZ 14 -> 30](schunix-dirsiz-14.md) — filenames used to truncate silently; fixed by holding the HTree bucket at 256 bytes.
|
||||
- [Linux open flags](schunix-linux-open-flags.md) — include/fcntl.h must hold Linux's values; a mismatch made `>>` truncate.
|
||||
- [Linux open flags](schunix-linux-open-flags.md) — include/uapi/fcntl.h must hold Linux's values; a mismatch made `>>` truncate.
|
||||
- [Shared memory and mmap](schunix-shm-and-mmap.md) — shm + file-backed mmap work; pages you don't own must never reach kfree.
|
||||
- [Wall clock](schunix-wall-clock.md) — the RTC was never read, so `date` said 1970; kernel/core/time.c fixes it, plus the stale-image trap.
|
||||
- [TTF rasteriser](schunix-ttf-rasteriser.md) — glyf outlines (not CFF, and why); the composite-glyph trap that loses the letter "i".
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ The filesystem is called **SchFS** — not "SchFS v2". Design: `docs/architectur
|
|||
**Phase 1 is done** (2026-08-01): the copy-on-write B-tree exists and passes its
|
||||
torture harness.
|
||||
|
||||
- `include/schfs.h` — on-disk format: 4096-byte blocks, 24-byte
|
||||
- `include/fs/schfs.h` — on-disk format: 4096-byte blocks, 24-byte
|
||||
`(objectid, type, offset)` keys, node header with a self-pointer, uberblock ring.
|
||||
- `kernel/fs/schfs/btree.{c,h}` — portable C against an abstract
|
||||
`struct schfs_bdev`, so the same code runs on a host file and in the kernel.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ mkdir /mnt && mount -t schfs /dev/hdb /mnt
|
|||
|
||||
then ordinary `ls`/`cat`/`>`/`>>`/`mkdir`/`cp`/`rm`/`rmdir` all work on it.
|
||||
|
||||
**The VFS now has a real dispatch layer**: `struct fs_ops` in `include/file.h`,
|
||||
**The VFS now has a real dispatch layer**: `struct fs_ops` in `include/fs/file.h`,
|
||||
one table per filesystem, chosen by `iget()` from the device number and hung off
|
||||
the inode. v1's implementations kept their bodies and are named `v1_*`; SchFS's
|
||||
live in `kernel/fs/schfs/vfs.c`. **Adding a filesystem is a new table, not
|
||||
|
|
@ -105,7 +105,7 @@ retry.
|
|||
if (dev == PROCFS_DEV) return &procfs_ops;
|
||||
return &v1_ops; // legacy, only because it is the default
|
||||
|
||||
`struct fs_ops` (include/file.h:35) is a complete vtable -- iload, istore,
|
||||
`struct fs_ops` (include/fs/file.h:35) is a complete vtable -- iload, istore,
|
||||
ifree, read, write, truncate, dirops -- and **SchFS implements all of it**. So
|
||||
`fs.c` is no longer "the filesystem"; it is the fallback branch. Killing it is
|
||||
three edits, not a rewrite:
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ the bug.
|
|||
|
||||
Three coupled changes, all required together:
|
||||
|
||||
1. `BSIZE` 1024 → 4096 (`include/fs.h`). Keep it equal to `SCHFS_BLKSIZE`.
|
||||
1. `BSIZE` 1024 → 4096 (`include/fs/fs.h`). Keep it equal to `SCHFS_BLKSIZE`.
|
||||
2. `NBUF` 90 → 256 blocks (1 MB). At 90 KB the cache was **smaller than the
|
||||
binary every command execs**, so nothing was ever resident on the next
|
||||
command. This is what makes the *second* command fast.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ clone has no `/etc/passwd` or `/etc/motd` (still an open gap).
|
|||
malloc, no printf, no strlen. Static storage and hand-rolled helpers only.
|
||||
|
||||
**`getdents64` was exposed for this.** The kernel has had syscall 96/217 since
|
||||
the Linux ABI landed, but nothing declared it in `include/user.h` or
|
||||
the Linux ABI landed, but nothing declared it in `include/uapi/user.h` or
|
||||
`lib/usys.S`, so first-party programs could not list a directory at all. Step
|
||||
records by `d_reclen`, never `sizeof`.
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ hands over long mode already, and dropping back down to climb out again is a
|
|||
mode switch whose failure mode is a triple fault with no console. So entry.S
|
||||
publishes a 64-bit entry the same way it publishes the multiboot header: magic
|
||||
`SCH64BOO`, 8-byte aligned in the first 16 KB, then a 64-bit physical address.
|
||||
`include/schboot.h` owns the constants so loader and kernel cannot disagree —
|
||||
`include/arch/schboot.h` owns the constants so loader and kernel cannot disagree —
|
||||
the first attempt defined them twice and searched for `SCH6` while the
|
||||
assembler had written `6HCS`.
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ 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/logo.h`. Run `make logo` — it is
|
||||
*not* a build dependency, and `include/logo.h` is committed, on the same
|
||||
reasoning as `include/font.h`. The mask is coverage, not colour, so the palette
|
||||
stays in [[schunix-console-tty]]'s `include/theme.h`; the loader composites it in
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ Two real bugs found in the Makefile while doing this:
|
|||
|
||||
- **`$(BUILD)/kernel/**/*.d` only matched one directory level.** make's wildcard
|
||||
has no recursive `**`. `arch/x86_64/` and `fs/schfs/` therefore had **no
|
||||
header dependency tracking at all** — editing `include/schfs.h` left stale
|
||||
header dependency tracking at all** — editing `include/fs/schfs.h` left stale
|
||||
objects that linked fine. It uses `$(shell find ...)` now.
|
||||
- **`CFLAGS` is recursively expanded and had a `$(shell)` appended**, so the
|
||||
stack-protector probe re-ran on every expansion: one extra gcc per object
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ you whether the escape parser works; it holds the raw bytes either way. Use
|
|||
`pwsh -File tools/ttyshot.ps1`, which drives colour/cursor/erase/UTF-8 and
|
||||
screendumps the result.
|
||||
|
||||
**The font is CP437, not Latin-1.** `include/font.h`'s per-glyph comments
|
||||
**The font is CP437, not Latin-1.** `include/gfx/font.h`'s per-glyph comments
|
||||
label index N with Unicode codepoint N, which is fiction above 127: index 0xE9
|
||||
is annotated "e-acute" and draws a capital theta. Trusting it turned "café"
|
||||
into "caf" + theta. `console.c` maps Unicode through `latin1_to_cp437[]` plus
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ 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/logo.h`, the same mask the loader splash and
|
||||
`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,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ metadata:
|
|||
modified: 2026-08-08T18:05:13.551Z
|
||||
---
|
||||
|
||||
Built 2026-08-08. `include/device.h` + `kernel/dev/device.c`, readable at
|
||||
Built 2026-08-08. `include/dev/device.h` + `kernel/dev/device.c`, readable at
|
||||
`/proc/devices`. Written up in `docs/architecture/devices.md`. Supersedes the two separate
|
||||
arrays in `kernel/drivers/registry.c` as the answer to "what is attached".
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ break both assumptions** and needs a spinlock plus a reader lock in procfs.
|
|||
|
||||
## The display class
|
||||
|
||||
`include/display.h` + ops in `kernel/dev/vga.c`, published on the device by
|
||||
`include/gfx/display.h` + ops in `kernel/dev/vga.c`, published on the device by
|
||||
`vga_pci_driver.ops`. `struct pci_driver` gained an `ops` field for this —
|
||||
**it has to live on the driver, not be set inside probe()**, because
|
||||
`pci_bind()` registers the device *after* probe returns.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ metadata:
|
|||
type: project
|
||||
---
|
||||
|
||||
Found 2026-08-09 while staging fonts. `DIRSIZ` in `include/fs.h` is **14**, an
|
||||
Found 2026-08-09 while staging fonts. `DIRSIZ` in `include/fs/fs.h` is **14**, an
|
||||
xv6 inheritance, and the v1 filesystem truncates to it **silently**.
|
||||
|
||||
`JetBrainsMono-Regular.ttf` was stored as `JetBrainsMono-`. Two consequences,
|
||||
|
|
@ -30,7 +30,7 @@ of every directory.
|
|||
|
||||
DIRSIZ 30 makes `struct dirent` exactly **32 bytes**, so a 256-byte bucket holds
|
||||
**8** slots instead of 16 and **every byte offset in the layout is unchanged**.
|
||||
`DIRENT_BUCKET_BYTES` in `include/fs.h` is now the constant the maths is written
|
||||
`DIRENT_BUCKET_BYTES` in `include/fs/fs.h` is now the constant the maths is written
|
||||
against; `kernel/fs/fs.c` and `tools/mkfs.c` both use it instead of
|
||||
`16 * sizeof(struct dirent)`. Cost: more overflow use in heavily collided
|
||||
directories.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ metadata:
|
|||
**Built 2026-08-04**, before USB, because xHCI, any NIC and virtio-gpu all
|
||||
need the same three things and none of them existed.
|
||||
|
||||
- **`kernel/dev/irq.c` + `include/irq.h`** — `irq_register(irq, fn, arg,
|
||||
- **`kernel/dev/irq.c` + `include/core/irq.h`** — `irq_register(irq, fn, arg,
|
||||
name, level_low)`. `trap.c` used to be a switch listing every interrupt by
|
||||
name, which cannot work for a PCI device: its line comes out of config
|
||||
space at probe time, so there is no constant to write a `case` label for.
|
||||
|
|
@ -19,7 +19,7 @@ need the same three things and none of them existed.
|
|||
handler must recognise that its own device is idle and return.
|
||||
Registration publishes an entry then bumps `n` with a barrier, so dispatch
|
||||
needs no lock. `/proc/interrupts` (minor 12) shows counts and trigger mode.
|
||||
- **`kernel/core/dma.c` + `include/dma.h`** — `dma_alloc(size, align)` /
|
||||
- **`kernel/core/dma.c` + `include/core/dma.h`** — `dma_alloc(size, align)` /
|
||||
`dma_free(p, size)` (Linux's contract: caller remembers the size). Carved
|
||||
off the top of physical memory in `main.c` *before* `kinit1`, because
|
||||
kalloc's free list makes no contiguity promise. x86 PCI is cache coherent
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ One directory per *driver*, not per class (Nexoniarz asked for this
|
|||
specifically), so a driver that grows a register header, a second source file or
|
||||
a firmware blob has somewhere to put it.
|
||||
|
||||
Matches `DEVCLASS_*` in `include/device.h`. Flat was eight files with four
|
||||
Matches `DEVCLASS_*` in `include/dev/device.h`. Flat was eight files with four
|
||||
called `usb_something`, and each driver added made it worse.
|
||||
|
||||
**Makefile note:** the compile rule is now
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ metadata:
|
|||
|
||||
**`/dev/fb0` (major 2) is a real framebuffer device** as of 2026-08-04:
|
||||
`kernel/dev/fb.c` (read/write by byte offset, plus `fb_ioctl`), declared in
|
||||
`include/fb.h`. Before this it was wired to `{ nullread, nullwrite }` — writing
|
||||
`include/gfx/fb.h`. Before this it was wired to `{ nullread, nullwrite }` — writing
|
||||
pixels to it succeeded and did nothing.
|
||||
|
||||
**`include/fb.h` holds Linux's fbdev request numbers and struct layouts**
|
||||
**`include/gfx/fb.h` holds Linux's fbdev request numbers and struct layouts**
|
||||
(`FBIOGET_VSCREENINFO` 0x4600, `fb_var_screeninfo` 160 bytes,
|
||||
`fb_fix_screeninfo` 80 bytes). Same reasoning as
|
||||
[[schunix-linux-open-flags]]: a shared number must mean the shared thing, or a
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ metadata:
|
|||
---
|
||||
|
||||
**Never reach a device's registers with `P2V(bar.base)`.** Use
|
||||
`ioremap(pa, size)` from `kernel/arch/x86_64/vm.c` (declared in `include/defs.h`).
|
||||
`ioremap(pa, size)` from `kernel/arch/x86_64/vm.c` (declared in `include/core/defs.h`).
|
||||
|
||||
Every driver used to do the `P2V` thing, which silently assumes the BAR lands
|
||||
inside the 0-4 GB that `kvmalloc()` direct-maps with four 1 GB pages. Under
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
name: schunix-linux-open-flags
|
||||
description: "include/fcntl.h must hold Linux's open-flag values — the userland is all Linux-ABI, and a mismatch silently corrupts files"
|
||||
description: "include/uapi/fcntl.h must hold Linux's open-flag values — the userland is all Linux-ABI, and a mismatch silently corrupts files"
|
||||
metadata:
|
||||
node_type: memory
|
||||
type: project
|
||||
|
|
@ -8,7 +8,7 @@ metadata:
|
|||
modified: 2026-08-03T13:59:19.392Z
|
||||
---
|
||||
|
||||
**`include/fcntl.h` holds Linux x86-64 open-flag values, and must keep holding
|
||||
**`include/uapi/fcntl.h` holds Linux x86-64 open-flag values, and must keep holding
|
||||
them.** Every program in the userland is built against a libc that sends Linux
|
||||
values; the kernel reads them with these constants. Do not "tidy" them into a
|
||||
neat sequence — they are an external interface.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,6 @@ driver in brackets (`[-]` when unclaimed). Under QEMU's default i440fx it
|
|||
should show six devices; `tools/bootcheck.ps1` asserts on the host bridge and
|
||||
the IDE controller by ID, and on `[vga]` having bound.
|
||||
|
||||
`inl`/`outl` were added to include/x86.h for this — config space is only
|
||||
`inl`/`outl` were added to include/arch/x86.h for this — config space is only
|
||||
reachable in dwords, so `pci_read16`/`pci_read8` shift and mask the containing
|
||||
dword rather than doing a narrower bus cycle.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ metadata:
|
|||
modified: 2026-08-08T16:22:01.468Z
|
||||
---
|
||||
|
||||
Built 2026-08-08. `kernel/core/qr.c` + `include/qr.h`, the Phase 8 crash channel
|
||||
Built 2026-08-08. `kernel/core/qr.c` + `include/gfx/qr.h`, the Phase 8 crash channel
|
||||
(see [[schunix-crash-screen]] and `docs/plan/roadmap.md`).
|
||||
|
||||
**Wired into the crash screen the same day.** `panic.c` builds a compact payload
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ metadata:
|
|||
modified: 2026-08-05T07:12:20.950Z
|
||||
---
|
||||
|
||||
Unix domain sockets (`kernel/net/unix.c`, `include/socket.h`, `kernel/sys/sys_net.c`)
|
||||
and raw input events (`kernel/dev/input.c`, `include/input.h`) are both done and
|
||||
Unix domain sockets (`kernel/net/unix.c`, `include/net/socket.h`, `kernel/sys/sys_net.c`)
|
||||
and raw input events (`kernel/dev/input.c`, `include/dev/input.h`) are both done and
|
||||
verified — `tools\bootcheck.ps1 -Sock` and `-Evdev`.
|
||||
|
||||
**One lock for the whole socket table, deliberately.** A pipe gets a lock per
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ SYSCALL_ALIAS(linux_nr, name) // extra Linux number -> existing handler
|
|||
|
||||
and implemented as `SYSCALL_DEFINE(name) { ... }` in a `kernel/sys/sys_*.c`.
|
||||
|
||||
Generated from that one line: the `SYS_*` enum (`include/syscall.h`), the
|
||||
Generated from that one line: the `SYS_*` enum (`include/core/syscall.h`), the
|
||||
dispatch table (`kernel/sys/syscall.c`), and the Linux ABI translation map
|
||||
(`kernel/sys/linux_abi.c`).
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ metadata:
|
|||
modified: 2026-08-08T22:45:34.934Z
|
||||
---
|
||||
|
||||
Built 2026-08-09. `include/text.h` + `kernel/dev/text.c`. Nexoniarz: "using ANSI
|
||||
Built 2026-08-09. `include/gfx/text.h` + `kernel/dev/text.c`. Nexoniarz: "using ANSI
|
||||
fonts in 2026 is a not funny joke."
|
||||
|
||||
**The font was never the problem — the grid was.** The console indexes
|
||||
|
|
@ -44,7 +44,7 @@ a useful side-by-side.
|
|||
|
||||
## Traps hit
|
||||
|
||||
- `include/font.h` **defines** `font_data` rather than declaring it, so
|
||||
- `include/gfx/font.h` **defines** `font_data` rather than declaring it, so
|
||||
including it from a second file duplicates the symbol under `-fno-common`.
|
||||
text.c declares `extern unsigned char font_data[256][16];` instead; the header
|
||||
is generated data and is better left alone.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ metadata:
|
|||
type: project
|
||||
---
|
||||
|
||||
Built 2026-08-09. `include/ttf.h` + `kernel/dev/ttf.c`, the second `font_ops`
|
||||
Built 2026-08-09. `include/gfx/ttf.h` + `kernel/dev/ttf.c`, the second `font_ops`
|
||||
provider behind [[schunix-text-rendering]]. Host harness: `tools/ttftest.c` →
|
||||
`build/tools/ttftest font.ttf px "text" out.pgm`.
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ metadata:
|
|||
---
|
||||
|
||||
Written 2026-08-08 from the OASIS virtio 1.1 specification (chapters 2, 4.1,
|
||||
5.7). `include/virtio.h` + `kernel/drivers/virtio_gpu.c`. Worked on the first
|
||||
5.7). `include/dev/virtio.h` + `kernel/drivers/virtio_gpu.c`. Worked on the first
|
||||
boot.
|
||||
|
||||
virtio-gpu: 1280x800, 4000 KB framebuffer, queue 64
|
||||
|
|
|
|||
Loading…
Reference in a new issue