udevd and a one-shot trigger run from schinit, 10-schos.conf no longer lists event0/event1, and the docs say what udev covers and what it does not. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
127 lines
7.6 KiB
Markdown
127 lines
7.6 KiB
Markdown
# The system, layer by layer
|
|
|
|
What SchOS is today. Everything in this directory is built and running; what is
|
|
merely intended lives in [../plan/](../plan/).
|
|
|
|
---
|
|
|
|
## The names, and what each one covers
|
|
|
|
`uname -s` reports `SchIFT`, the way every Unix reports its kernel rather than
|
|
its distribution.
|
|
|
|
| Layer | Name | What it is |
|
|
|---|---|---|
|
|
| System | **SchOS** | The distribution — kernel, userland, tooling |
|
|
| Kernel | **SchIFT** | Multi-core x86-64 kernel with a modular VFS |
|
|
| Filesystem | **SchFS** | Transactional, copy-on-write, the root filesystem |
|
|
| API | **SchAPI** | The native programming interface — *designed, not built* |
|
|
| Packages | **apk** | Alpine's package manager manages the root; SchOS itself is the package `schos-base` |
|
|
|
|
Twelve virtual terminals sit under all of it -- `/dev/tty1`..`tty12`, Ctrl+Alt+F1..F12
|
|
or `chvt N` -- each with its own screen, line discipline and foreground process group. See
|
|
[terminals.md](terminals.md).
|
|
|
|
---
|
|
|
|
## The stack, bottom to top
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────┐
|
|
│ Xorg + Window Maker · Alpine's packages (apk) │ desktop, userland
|
|
│ toybox mksh musl first-party cmd/ │
|
|
├─────────────────────────────────────────────────┤
|
|
│ vgpud, ldlsd — drivers that are ordinary │
|
|
│ processes (and Linux's r8169 inside ldlsd) │
|
|
├─────────────────────────────────────────────────┤
|
|
│ schinit — PID 1, job manifests, supervision │
|
|
├─────────────────────────────────────────────────┤
|
|
│ syscall table — Linux numbering, one .inc file │ ← the ABI seam
|
|
╞═════════════════════════════════════════════════╡
|
|
│ VFS │ sockets │ signals │ mmap │ poll │ procfs │
|
|
├──────┴─────────┴─────────┴──────┴──────┴────────┤
|
|
│ SchFS │ lwIP │ vt/gfx │ buffer cache │
|
|
├─────────┴────────┴──────────┴───────────────────┤
|
|
│ device model — class vtables, bus binding │ ← the driver seam
|
|
├─────────────────────────────────────────────────┤
|
|
│ /dev/pci — MMIO, DMA and IRQs to a process │ ← the eviction seam
|
|
├─────────────────────────────────────────────────┤
|
|
│ drivers: xHCI AHCI NVMe e1000 8139 r8169 AC97 │
|
|
│ virtio-gpu VBE IDE PS/2 I2C-HID │
|
|
├─────────────────────────────────────────────────┤
|
|
│ scheduler │ paging │ traps │ IRQ │ SMP │ DMA │ SchIFT core
|
|
└─────────────────────────────────────────────────┘
|
|
▲
|
|
UEFI loader (boot/uefi)
|
|
```
|
|
|
|
Three seams matter. Above the **syscall table**, software is ordinary and
|
|
portable — musl and toybox are unmodified. Below the **device model**, a driver
|
|
never names its consumer and a consumer never names a driver. And at
|
|
**`/dev/pci`**, a driver stops having to be in the kernel at all: a process is
|
|
handed a device's registers, DMA memory and interrupts, and the in-kernel driver
|
|
that held it releases it cleanly. `vgpud` is the virtio-gpu driver living out
|
|
there today, and `ldlsd` runs Linux's own drivers the same way. See
|
|
[devices.md](devices.md) and [ldls.md](ldls.md).
|
|
|
|
---
|
|
|
|
## Where it came from
|
|
|
|
SchOS began as [xv6](https://github.com/mit-pdos/xv6-public) and is now mostly
|
|
something else. What survives from xv6 is the *shape* of the process table, the
|
|
sleep/wakeup discipline, and the buffer cache. What has been replaced: the
|
|
scheduler and trap path (rewritten for x86-64 and for more than one processor),
|
|
the memory manager, the entire filesystem, the syscall layer, and every driver.
|
|
|
|
That inheritance is worth knowing when reading the code, because the parts that
|
|
still look like xv6 follow xv6's conventions and the parts that do not, do not.
|
|
|
|
---
|
|
|
|
## The documents
|
|
|
|
Read in this order if you are new:
|
|
|
|
| | |
|
|
|---|---|
|
|
| [boot.md](boot.md) | Firmware to the first userspace process. The shortest path through the whole system. |
|
|
| [kernel.md](kernel.md) | Memory, processes, scheduling, traps, signals, SMP. |
|
|
| [syscalls.md](syscalls.md) | The one table everything is generated from, and how a musl binary runs unmodified. |
|
|
| [scheduler.md](scheduler.md) | Fair share by virtual runtime, slices, and `nice`. |
|
|
| [filesystem.md](filesystem.md) | The VFS, the buffer cache, mounts, procfs. |
|
|
| [schfs.md](schfs.md) | The copy-on-write root filesystem. |
|
|
| [fat.md](fat.md) | FAT12/16/32 with long names: USB sticks, SD cards, the ESP. |
|
|
| [devices.md](devices.md) | Buses, classes, binding, and the vtables consumers talk to. |
|
|
| [usb.md](usb.md) | xHCI, the USB core, and the three class drivers. |
|
|
| [udev.md](udev.md) | eudev on SchOS: the device table, the `/sys` tree, uevents, datagram sockets. |
|
|
| [graphics.md](graphics.md) | Framebuffer, `/dev/fb0`, text rendering, the console, PSOGM and GMMOS. |
|
|
| [desktop.md](desktop.md) | Xorg on the framebuffer, Window Maker, and what they stand on. |
|
|
| [packages.md](packages.md) | The apk root: Alpine's packages, and SchOS as one of them. |
|
|
| [scff.md](scff.md) | The compressed image the live root ships as. |
|
|
| [terminals.md](terminals.md) | The twelve virtual terminals, ptys, and handing one to a display server. |
|
|
| [networking.md](networking.md) | NIC drivers, lwIP, and the socket families. |
|
|
| [audio.md](audio.md) | `/dev/dsp`, AudioEngine, and the AC'97 driver under it. |
|
|
| [init.md](init.md) | `schinit`, PID 1 as a role, and the job manifests. |
|
|
| [debugging.md](debugging.md) | Symbols, a log that outlives the kernel, and asking the kernel a question. |
|
|
| [ldls.md](ldls.md) | Running somebody else's drivers: a Linux `.ko`, in a process, reaching hardware through `/dev/pci`. |
|
|
|
|
---
|
|
|
|
## Three rules that hold across all of it
|
|
|
|
**The kernel and the host tools compile the same SchFS source.** `mkschfs`
|
|
cannot disagree with the kernel about the on-disk format, because there is only
|
|
one implementation. Format bugs are found on the host, where a test takes a
|
|
second instead of a boot.
|
|
|
|
**Syscalls are declared in exactly one place.** `kernel/sys/table.inc`.
|
|
The constants, the dispatch table and the Linux translation map are all
|
|
generated from it, so a syscall cannot be half-registered.
|
|
|
|
**A list you can read beats a list assembled by side effects.** Drivers are
|
|
written out by hand in `kernel/drivers/registry.c` rather than collected by a
|
|
linker section, and platform devices are registered in one function rather than
|
|
inside each driver's init. The tradeoff is deliberate: self-registration is
|
|
nicer to write, and it means the list of what is in your kernel is not written
|
|
down anywhere you can read.
|