The point is not a disclaimer, it is the argument: the tool is not the measure of a project. Code nobody understands is bad code whoever typed it, and code whose every decision can be explained is good code by the same standard. Placed next to a link to history/ on purpose. That directory is where the claim can be checked -- the bugs are written up in full, including the wrong hypotheses and the measurements that killed them. An explanation you can follow is the evidence; a byline is not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
313 lines
12 KiB
HTML
313 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>SchOS — a 64-bit operating system written from scratch</title>
|
|
<meta name="description" content="SchOS is a from-scratch x86-64 operating system: the SchIFT kernel, the SchFS copy-on-write filesystem, a UEFI loader, and a userland that runs unmodified musl and toybox.">
|
|
<link rel="icon" href="Assets/shift.svg" type="image/svg+xml">
|
|
<link rel="stylesheet" href="style.css">
|
|
</head>
|
|
<body>
|
|
|
|
<header class="top">
|
|
<div class="wrap">
|
|
<a class="brand" href="#top">
|
|
<img src="Assets/shift.svg" alt="">
|
|
SchOS
|
|
</a>
|
|
<a class="pride" href="#pride-note" title="SchOS stands with the LGBTQIAP+ community — every month of the year">
|
|
<img src="Assets/pride.svg" alt="Progress Pride flag">
|
|
</a>
|
|
<nav>
|
|
<a href="#origin">Origin</a>
|
|
<a href="#stack">The stack</a>
|
|
<a href="#what">What it has</a>
|
|
<a href="#numbers">Numbers</a>
|
|
<a href="docs.html">Docs</a>
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
<main id="top">
|
|
|
|
<section class="hero">
|
|
<div class="wrap">
|
|
<div>
|
|
<h1><img class="mark" src="Assets/shift.svg" alt="">SchOS</h1>
|
|
<p>
|
|
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 <code>musl</code> and <code>toybox</code> on top.
|
|
</p>
|
|
<div class="cta">
|
|
<a class="btn primary" href="#what">What it has</a>
|
|
<a class="btn" href="#origin">Where it started</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="console" aria-label="Boot log">
|
|
<div class="console-bar">
|
|
<i class="dot live"></i> ttyS0
|
|
<span>SchIFT</span>
|
|
</div>
|
|
<pre id="bootlog" aria-live="polite"></pre>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="origin" class="reveal">
|
|
<div class="wrap">
|
|
<p class="eyebrow">Origin</p>
|
|
<h2>It started as a teaching kernel and stopped being one</h2>
|
|
<p class="lede">
|
|
SchOS began as <a href="https://github.com/mit-pdos/xv6-public">xv6</a>, 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.
|
|
</p>
|
|
|
|
<div class="origin-grid">
|
|
<div class="step">
|
|
<span class="when">First</span>
|
|
<h3>64-bit, and more than one core</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
<div class="step">
|
|
<span class="when">Then</span>
|
|
<h3>Its own filesystem</h3>
|
|
<p>
|
|
xv6's log-structured filesystem was replaced by <b>SchFS</b>: 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.
|
|
</p>
|
|
</div>
|
|
<div class="step">
|
|
<span class="when">Then</span>
|
|
<h3>A Linux-shaped ABI</h3>
|
|
<p>
|
|
The syscall table adopted Linux numbering, which is what makes an
|
|
unmodified musl and an unmodified toybox run. The table is one
|
|
<code>.inc</code> file, and it is the seam the whole system is built around.
|
|
</p>
|
|
</div>
|
|
<div class="step">
|
|
<span class="when">Now</span>
|
|
<h3>Hardware, not emulation</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="stack" class="reveal">
|
|
<div class="wrap">
|
|
<p class="eyebrow">Architecture</p>
|
|
<h2>Two seams hold the whole thing together</h2>
|
|
<p class="lede">
|
|
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.
|
|
Everything else is arrangement.
|
|
</p>
|
|
|
|
<div class="stack">
|
|
<div class="layer"><span class="name">userland</span><span class="what">toybox, mksh, musl, and the first-party programs in <code>cmd/</code></span></div>
|
|
<div class="layer"><span class="name">schinit</span><span class="what">PID 1 — job manifests and supervision</span></div>
|
|
<div class="layer seam"><span class="name">syscall table</span><span class="what">Linux numbering, one <code>.inc</code> file — the ABI seam</span></div>
|
|
<div class="layer"><span class="name">kernel services</span><span class="what">VFS, sockets, signals, mmap, poll, procfs</span></div>
|
|
<div class="layer"><span class="name">subsystems</span><span class="what">SchFS, lwIP, text and graphics, the buffer cache</span></div>
|
|
<div class="layer seam"><span class="name">device model</span><span class="what">class vtables and bus binding — the driver seam</span></div>
|
|
<div class="layer"><span class="name">drivers</span><span class="what">xHCI, e1000, virtio-gpu, VBE, IDE, PS/2</span></div>
|
|
<div class="layer"><span class="name">SchIFT core</span><span class="what">scheduler, paging, traps, IRQ, SMP, DMA</span></div>
|
|
<div class="layer"><span class="name">boot</span><span class="what">the UEFI loader in <code>boot/uefi</code></span></div>
|
|
</div>
|
|
|
|
<p class="seam-note">
|
|
<code>uname -s</code> reports <b>SchIFT</b> — the kernel — the way every Unix
|
|
reports its kernel rather than its distribution.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="what" class="reveal">
|
|
<div class="wrap">
|
|
<p class="eyebrow">What it has</p>
|
|
<h2>Built and running, and honest about the rest</h2>
|
|
<p class="lede">
|
|
Every card marked <b>runs</b> is in the tree and works today. The tags are
|
|
not aspirational; the things that are not finished say so.
|
|
</p>
|
|
|
|
<div class="cards">
|
|
<div class="card">
|
|
<span class="tag runs">runs</span>
|
|
<h3><img class="cardmark" src="Assets/uberblock.svg" alt="">SchFS</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag runs">runs</span>
|
|
<h3>SMP x86-64 kernel</h3>
|
|
<p>
|
|
Four-level paging, multiple cores, preemptive scheduling, a calibrated
|
|
LAPIC timer, real signal delivery and job control. 205 syscalls on
|
|
Linux numbering.
|
|
</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag runs">runs</span>
|
|
<h3>Networking</h3>
|
|
<p>
|
|
An e1000 driver under lwIP, with sockets for AF_INET, AF_UNIX and
|
|
AF_NETLINK. DHCP brings the interface up at boot; <code>ping</code>
|
|
reaches the outside world.
|
|
</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag runs">runs</span>
|
|
<h3>UEFI boot</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag runs">runs</span>
|
|
<h3>USB</h3>
|
|
<p>
|
|
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.
|
|
</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag runs">runs</span>
|
|
<h3>A real userland</h3>
|
|
<p>
|
|
musl and toybox, both unmodified, plus mksh as <code>/bin/sh</code>.
|
|
<b>fastfetch</b> builds from upstream source with an empty
|
|
<code>patches/</code> directory — when it could not detect something, the
|
|
answer was to give the kernel what it was looking for.
|
|
</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag partial">in progress</span>
|
|
<h3>Schcom</h3>
|
|
<p>
|
|
The compositor that will own the display. v0 runs. The desktop above it
|
|
is the next large piece of work, and it is deliberately Wayland-shaped.
|
|
</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag planned">designed</span>
|
|
<h3>SchAPI</h3>
|
|
<p>
|
|
The native programming interface — specified, not built, and deliberately
|
|
so. It should be designed <i>from</i> the compositor's experience rather
|
|
than before it.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="numbers" class="reveal">
|
|
<div class="wrap">
|
|
<p class="eyebrow">Numbers</p>
|
|
<h2>The size of it</h2>
|
|
<div class="figures">
|
|
<div class="figure"><b>43,701</b><span>lines in <code>kernel/</code> and <code>include/</code></span></div>
|
|
<div class="figure"><b>205</b><span>syscalls, Linux numbering</span></div>
|
|
<div class="figure"><b>128</b><span>uberblock ring slots</span></div>
|
|
<div class="figure"><b>0</b><span>patches carried against fastfetch</span></div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="crash reveal">
|
|
<div class="wrap">
|
|
<img src="Assets/guru.svg" alt="Guru, the SchOS crash-screen icon">
|
|
<div>
|
|
<p class="eyebrow">When it stops</p>
|
|
<h2>PSOGM</h2>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<p>
|
|
This purple is <code>#4B1D9A</code>, 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.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="docs" class="reveal">
|
|
<div class="wrap">
|
|
<p class="eyebrow">Reading</p>
|
|
<h2>Where to look</h2>
|
|
<p class="lede">
|
|
The documentation is written to outlive the work. Anything finished is
|
|
described in <code>architecture/</code>; anything intended lives in
|
|
<code>plan/</code>; and the bugs worth remembering are kept in
|
|
<code>history/</code>, in full, including the wrong turns.
|
|
</p>
|
|
<p class="readerlink"><a class="btn primary" href="docs.html">Open the docs reader</a></p>
|
|
<div class="links">
|
|
<a class="link-card" href="docs.html?doc=architecture/README.md">
|
|
<b>Architecture</b><span>What the system is, layer by layer</span>
|
|
</a>
|
|
<a class="link-card" href="docs.html?doc=plan/1.0.md">
|
|
<b>The 1.0 definition</b><span>What is in, what is out, and why</span>
|
|
</a>
|
|
<a class="link-card" href="docs.html?doc=history/kernel.md">
|
|
<b>Kernel history</b><span>The bugs, and what each one taught</span>
|
|
</a>
|
|
<a class="link-card" href="docs.html?doc=guides/building.md">
|
|
<b>Building it</b><span>Toolchain, ports, and running under QEMU</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
</main>
|
|
|
|
<footer>
|
|
<div class="wrap">
|
|
<span>SchOS — kernel <b>SchIFT</b>, filesystem <b>SchFS</b>.</span>
|
|
<span class="mono">Apache-2.0, with the xv6-derived core under MIT.</span>
|
|
<span class="pride-note" id="pride-note">
|
|
<img src="Assets/pride.svg" alt="">
|
|
Built by, and for, people of every orientation and gender identity.
|
|
The flag stays up all year.
|
|
</span>
|
|
<span class="note" id="ai-note">
|
|
<b>On AI.</b>
|
|
Parts of SchOS were written with AI assistance, and that is not the measure
|
|
of anything. A project is good when the people building it understand what
|
|
was built, and bad when nobody does — whoever, or whatever, typed it. Vibe
|
|
your way through and you get something no one can fix. Stay in the loop and
|
|
you get a system you can explain line by line. The bug writeups in
|
|
<a href="docs.html?doc=history/kernel.md">history/</a> are where that gets
|
|
checked, including the wrong turns.
|
|
</span>
|
|
</div>
|
|
</footer>
|
|
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html>
|