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:
Nexoniarz 2026-10-23 15:05:12 +02:00
commit a1c965da1e
267 changed files with 1560 additions and 1440 deletions

46
include/core/sbuf.h Normal file
View file

@ -0,0 +1,46 @@
#pragma once
#include "core/types.h"
// A bounded string builder, because there is no snprintf in this kernel.
//
// These lived inside kernel/dev/procfs.c, where they were written, and were
// static to it. The debugger's introspection registry needs the same thing --
// a subsystem rendering its own state into a caller's buffer, with no
// allocation and no way to run off the end -- and the choice was to write a
// second set or to move this one. See docs/architecture/debugging.md, D2.
//
// Nothing here can overflow: every writer checks cap, and a full buffer
// silently drops the rest. That is the right trade for something whose callers
// are a /proc read and a crash-time dump; a builder that can fail is a builder
// every caller has to check, and none of them would.
struct sbuf {
char *p;
int len;
int cap;
};
void sb_putc(struct sbuf *sb, char c);
void sb_puts(struct sbuf *sb, const char *s);
// A string in a fixed-width column, space-padded. Over-long values run past
// their column rather than being truncated: a misaligned row is easier to read
// than a mangled name.
void sb_pad(struct sbuf *sb, const char *s, int width);
// Four lowercase hex digits, zero-padded. PCI and USB identifiers are always
// written this way, and a lookup table keyed on "8086:100e" does not match
// "8086:100E" or "8086:10e".
void sb_puthex4(struct sbuf *sb, uint32 v);
void sb_putu(struct sbuf *sb, uint64 v);
// Zero-padded hex of a given width, for addresses.
void sb_puthex(struct sbuf *sb, uint64 v, int digits);
// A decimal number in a right-aligned column, so tables of sizes line up.
void sb_putu_pad(struct sbuf *sb, uint64 v, int width);
// "<label><value> <unit>\n" -- the shape almost every /proc line takes.
void sb_kv(struct sbuf *sb, const char *label, uint64 v, const char *unit);