SchOS/include/core/param.h
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

72 lines
3.8 KiB
C

#pragma once
// The timer interrupt rate the kernel is built around. Everything that turns
// ticks into a duration divides by this. It used to be the literal 100 written
// out at each site, which made it look like a fact about the hardware; it is
// not. It is a target, and kernel/arch/x86_64/lapic.c calibrates the LAPIC
// timer against the PIT to actually hit it.
#define HZ 100 // timer interrupts per second
// The tick rate the *user-space ABI* is defined in, which is a different thing
// from HZ and must not follow it. glibc and musl both answer sysconf(_SC_CLK_TCK)
// with a hardcoded 100, so times() and /proc/stat are read as hundredths of a
// second no matter what the kernel's internal rate is. Linux calls this USER_HZ
// and scales at the syscall boundary; so does SchOS, in the two places below.
#define USER_HZ 100
// Converting a POSIX timespec/timeval into ticks. These used to appear as the
// bare literals 10000000 and 10000 at each call site, where they looked like
// magic numbers rather than what they are: the length of one tick, expressed
// in the units the caller happens to be using.
#define NSEC_PER_TICK (1000000000 / HZ)
#define USEC_PER_TICK (1000000 / HZ)
#define MSEC_PER_TICK (1000 / HZ)
#define NPROC 128 // maximum number of processes
#define KSTACKSIZE 8192 // per-process kernel stack; see kstacks[] in proc.c
#define KSTACK_CANARY 0xDEADC0DEDEADC0DEULL // sentinel at kstack[0], see kstack_check_canary()
#define NCPU 64 // maximum number of CPUs
#define NOFILE 128 // open files per process
#define NFILE 512 // open files per system
#define NINODE 200 // maximum number of active i-nodes
#define NDEV 13 // maximum major device number
#define RAMDISK_DEV 2 // memory-backed block device (kernel/dev/ramdisk.c)
#define USBDISK_DEV 3 // USB mass storage (kernel/drivers/usb_storage.c)
// Device the root filesystem is mounted from. Building with RAMROOT=1 defines
// RAMDISK_ROOT and boots from the SCHFS image linked into the kernel instead
// of the IDE disk, leaving the physical disk free to be reformatted from a
// running system. See kernel/dev/ramdisk.c.
#ifdef RAMDISK_ROOT
#define ROOTDEV RAMDISK_DEV
#else
#define ROOTDEV 1 // device number of file system root disk
#endif
// exec's limits, Linux's: ARG_MAX bytes of argument and environment strings
// and their pointers together, and no one string over ARG_STRLEN_MAX (Linux's
// MAX_ARG_STRLEN). There is no limit on the count beyond that.
#define ARG_MAX (2 * 1024 * 1024)
#define ARG_STRLEN_MAX (128 * 1024)
#define MAXPATH 128 // max path
#define MAXOPBLOCKS 30 // max # of blocks any FS op writes
#define LOGSIZE (MAXOPBLOCKS*3) // max data blocks in on-disk log
// Disk block cache, in blocks. 256 * BSIZE = 1 MB.
//
// Was MAXOPBLOCKS*3 = 90 blocks, and at the old 1 KB BSIZE that is a 90 KB
// cache -- smaller than the toybox binary that every single command execs. So
// nothing was ever still resident on the next command and each one paid the
// full read again. 1 MB holds toybox with room to spare, which is what makes
// the *second* command fast rather than just the first.
//
// Sized rather than maximised: these are statically allocated in bio.c, so
// this is memory the system always spends. 1 MB is affordable on a machine
// with tens of megabytes; 8 MB would not be.
#define NBUF 256
#define FSSIZE 150000 // size of file system in blocks
// Network interfaces the stack will attach. Two is already an ordinary machine
// -- a laptop with Ethernet plus a virtual adapter -- and each one costs a
// struct netif, so the limit is about keeping a fixed array honest rather than
// about memory. Eight, since a dock's Ethernet and a phone tethered over USB
// sit beside the built-in ones.
#define NETIF_MAX 8