SchOS
A 64-bit operating system written from scratch — its own kernel, its own
filesystem, its own bootloader. It boots on UEFI, drives real hardware,
and runs unmodified musl and
toybox on top.
GPL-2.0-or-later · runs from RAM · writes nothing to your disks
Origin
It started as a teaching kernel and stopped being one
SchOS began as xv6, MIT's teaching operating system: 32-bit, single core, one filesystem, a few dozen syscalls. Almost none of that survives. What follows is what replaced it.
-
First
64-bit, and more than one core
Four-level paging, a real SMP bring-up, per-CPU state and a trap path that survives both. This is the part that invalidates most of what a 32-bit uniprocessor kernel assumes.
-
Then
Its own filesystem
xv6's log-structured filesystem was replaced by SchFS: a copy-on-write B-tree with an uberblock ring, extents and checksummed metadata. A crash leaves either the old tree or the new one.
-
Then
A Linux-shaped ABI
The syscall table adopted Linux numbering, which is what makes an unmodified musl and an unmodified toybox run. The table is one
.incfile, and it is the seam the whole system is built around. -
Then
Hardware, not emulation
A UEFI loader, xHCI and USB storage, an e1000 with a real TCP/IP stack, virtio-gpu and VBE framebuffers, and a device model where a driver never names its consumer.
-
Now
Drivers that are not in the kernel
A process can be handed a PCI device — its registers, its memory, its interrupts — and drive it. The GPU driver already runs that way. Nobody writes a driver for every device that exists; the answer is to stop requiring that they live inside.
Architecture
Three seams hold the whole thing together
Above the syscall table, software is ordinary and portable. Below the device
model, a driver never names its consumer and a consumer never names a driver.
And at /dev/pci, a driver stops needing to be in
the kernel at all. Everything else is arrangement.
cmd/
vgpud — a driver that is an ordinary process
.inc file — the ABI seam
SCM_RIGHTS, signals, mmap, poll, procfs
boot/uefi
uname -s reports SchIFT — the kernel — the
way every Unix reports its kernel rather than its distribution.
What it has
Built and running, and honest about the rest
Every card marked runs is in the tree and works today. The tags are not aspirational; the things that are not finished say so.
runs
SMP x86-64 kernel
runsNetworking
runsping reaches the outside world.
UEFI boot
runsUSB
runsVirtual terminals
runsAltGr+F1…F6,
which is the one chord a Linux host does not take for itself. The console
draws to whichever framebuffer is present, from the kernel's first line.
schinit
runsA real userland
runs/bin/sh.
fastfetch builds from upstream source with an empty
patches/ directory — when it could not detect
something, the answer was to give the kernel what it was looking for.
Drivers outside the kernel
runs/dev/pci hands a process a device: its
registers by mmap, physically contiguous
memory it can point the device at, and interrupts as something to
read(). The virtio-gpu driver already lives
out there.
Schcom
in progressSchAPI
designedHybrid
A driver can leave the kernel
Nobody writes a driver for every device that exists — not a project this size, and not any project. So the interesting question is not how to write more of them, but what a driver actually needs from a kernel, and whether it can have that from outside.
It needs
Its registers
mmap on /dev/pci,
where the offset is the physical address of a BAR. The kernel refuses any
offset that is not inside a BAR of a device this process was given, which
is what stops it being /dev/mem with extra steps.
It needs
Memory the device can reach
It needs
To be told when to look
read(), so they compose
with poll. The kernel masks the line and
leaves it masked until the driver writes back — because a PCI interrupt is
level-triggered, and nobody but the driver knows how to clear it at the device.
It needs
A descriptor to arrive
sendmsg with SCM_RIGHTS.
Handing a process the device it is allowed to touch and handing a
compositor a buffer turned out to be the same act, which is why one
primitive answered both.
$ vgpud vgpud: virtio-gpu at 00:03.0, currently held by virtio-gpu virtio-gpu: released to userspace; screen is the VBE framebuffer vgpud: claimed vgpud: display is 1280x800 vgpud: scanout is ours, framebuffer at physical 0x3eceb000 vgpud: mirroring the console
No syscall in that transcript knows it is talking about a GPU. The kernel handed over a PCI device; the process decided what it was. That is the property that makes the interface general — and the reason SchOS's own drivers are being moved out through it first, rather than shaping it around something foreign and hoping it fits.
Numbers
The size of it
kernel/ and include/
PSOGM
When the kernel panics it does not scroll a stack trace past you. It draws a full-screen report — what failed, where, and the state that mattered — and encodes the whole thing as a QR code so it can leave the machine without being retyped. It reaches every display the machine has, including the ones the kernel has handed to a userspace driver.
This purple is #4B1D9A, and the theme reserves
it for exactly this. Normal states are calm and dark; only failure is loud.
It is the one colour in the system that means something, which is why it
appears once on this page and nowhere else.
Reading
Where to look
The documentation is written to outlive the work. Anything finished is
described in architecture/; anything intended
lives in plan/; and the bugs worth remembering
are kept in history/, in full, including the
wrong turns.
Architecture
What the system is, layer by layer
The 1.0 definition
What is in, what is out, and why
Kernel history
The bugs, and what each one taught
Building it
Toolchain, ports, and running under QEMU
Try it
One ISO, one stick, nothing written to your disks
It runs from RAM and leaves the machine as it found it. Or skip the
stick entirely — make qemu is the same
system in a window.