SchIFT 0.1.0 · boots on real hardware

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

SchIFT — ttyS0 live

  

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.

  1. 1
    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.

  2. 2
    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.

  3. 3
    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 .inc file, and it is the seam the whole system is built around.

  4. 4
    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.

  5. 5
    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.

userland toybox, mksh, zsh, musl, and the first-party programs in cmd/
userspace drivers vgpud — a driver that is an ordinary process
schinit PID 1 — job manifests, supervision, reincarnation
syscall tableseam Linux numbering, one .inc file — the ABI seam
kernel services VFS, sockets and SCM_RIGHTS, signals, mmap, poll, procfs
subsystems SchFS, lwIP, virtual terminals, graphics, the buffer cache
device modelseam class vtables and bus binding — the driver seam
/dev/pciseam registers, DMA and interrupts to a process — the eviction seam
drivers xHCI, e1000, virtio-gpu, VBE, IDE, PS/2
SchIFT core scheduler, paging, traps, IRQ, SMP, DMA
boot the UEFI loader in 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.

SchFS

runs
Copy-on-write B-tree, a 128-slot uberblock ring, extents with refcounts and reflink, CRC32c on metadata, and free space derived from the tree rather than stored beside it — so there is no second structure to disagree with the first. There is nothing to repair after a crash.

SMP x86-64 kernel

runs
Four-level paging, multiple cores, preemptive scheduling, a calibrated LAPIC timer, real signal delivery and job control. 207 syscalls on Linux numbering.

Networking

runs
An e1000 driver under lwIP, with sockets for AF_INET, AF_UNIX and AF_NETLINK. DHCP brings the interface up at boot; ping reaches the outside world.

UEFI boot

runs
A PE/COFF loader built with clang and lld-link that sets up its own page tables and hands the kernel a framebuffer. No BIOS path, no chainloading.

USB

runs
xHCI, hubs, HID and mass storage — a keyboard and a USB disk that the kernel can mount, through the same device model as everything else.

Virtual terminals

runs
Six of them, each with its own cell grid, scrollback and foreground job — switched with AltGr+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

runs
PID 1 does almost nothing: it forks a supervisor, spawns jobs on its behalf, and reaps. The supervisor holds the manifests and the respawn policy, and if it dies PID 1 replaces it and hands back the children it was already watching. PID 1 can re-exec itself without dropping them.

A real userland

runs
musl and toybox, both unmodified, plus mksh as /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 progress
The compositor that will own the display. v0 runs, and descriptor passing — the one thing a Wayland client cannot do without — now exists. What a buffer still needs is a shareable memory object.

SchAPI

designed
The native programming interface — specified, not built, and deliberately so. It should be designed from the compositor's experience rather than before it.

Hybrid

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

Physically contiguous, and the process is told the physical address — which is the whole reason it cannot do this for itself. The arena is reserved at boot, before the general allocator gets anything.

It needs

To be told when to look

Interrupts arrive by 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 — tty1
$ 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

lines in kernel/ and include/
46,961
syscalls, Linux numbering
207
patches carried against fastfetch
0
When it stops Shift, the SchOS mark, as the crash screen draws it

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.

Open the docs reader

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.