Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
244 lines
12 KiB
Markdown
244 lines
12 KiB
Markdown
<div align="center">
|
||
|
||
<img src="docs/branding/shift.svg" alt="Shift, the SchOS mark" width="160">
|
||
|
||
# SchOS
|
||
|
||
**A 64-bit operating system, written from the metal up — and it runs Linux's software.**
|
||
|
||
SMP kernel · copy-on-write filesystem · Linux syscall ABI · Alpine packages · Xorg · Linux's own drivers
|
||
|
||
</div>
|
||
|
||
---
|
||
|
||
SchOS is a hobby operating system built by one person. It began as
|
||
[xv6](https://github.com/mit-pdos/xv6-public) and almost nothing of that is left:
|
||
the scheduler, the memory manager, the trap path and every driver have been
|
||
rewritten for x86-64 and for more than one processor, and the filesystem is a
|
||
different one. The syscall table speaks Linux's numbering, so **real Linux
|
||
programs run on it unmodified** — statically or dynamically linked, straight out
|
||
of Alpine's package repositories — and a desktop (Xorg and Window Maker) and a
|
||
web browser (NetSurf) come up on the framebuffer.
|
||
|
||
It is honest about being a hobby system: what is listed below has been *run*,
|
||
not inferred, and [the gaps](#not-there-yet) are listed as plainly as the
|
||
features. It boots from a USB stick on three different real machines.
|
||
|
||
## In numbers
|
||
|
||
<!-- stats:begin -->
|
||
| | |
|
||
|---|---|
|
||
| **First-party code** | 72,766 lines, plus 23,670 lines of comments (25%) in 307 files |
|
||
| **Kernel** (`kernel/`, `include/`) | 51,893 lines of code, 17,213 of comments |
|
||
| **Syscalls** | 215, of which 193 on Linux numbering |
|
||
| **Drivers** | 15 in the kernel |
|
||
| **First-party programs** | 29 in `cmd/` |
|
||
| **Alpine packages in the root** | 179, from 29 asked for in `ports/alpine/world` |
|
||
| **History** | 292 commits since 2026-08-09 (78 days) |
|
||
|
||
<details>
|
||
<summary>Lines by language</summary>
|
||
|
||
| Language | Code | Comments |
|
||
|---|--:|--:|
|
||
| C | 67,615 | 21,904 |
|
||
| Assembly | 1,750 | 336 |
|
||
| PowerShell | 1,362 | 638 |
|
||
| Python | 943 | 150 |
|
||
| Shell | 896 | 531 |
|
||
| Perl | 129 | 45 |
|
||
| Linker script | 71 | 66 |
|
||
|
||
</details>
|
||
|
||
<sub>Measured by <code>tools/python/stats.py</code>; first-party code only, so
|
||
<code>ports/</code> and generated tables are not counted.</sub>
|
||
<!-- stats:end -->
|
||
|
||
## What it is made of
|
||
|
||
| Layer | Name | What it is |
|
||
|---|---|---|
|
||
| System | **SchOS** | The distribution — kernel, userland, tooling |
|
||
| Kernel | **SchIFT** | Multi-core x86-64 kernel with a modular VFS and Linux's syscall ABI |
|
||
| Filesystem | **SchFS** | Transactional, copy-on-write, the root filesystem |
|
||
| Image format | **SCFF** | The SchOS Compressed File Format the live root ships in |
|
||
| Packages | **apk** | Alpine's package manager manages the root; SchOS itself is the package `schos-base` |
|
||
| Desktop | **Xorg + Window Maker** | Alpine's, on the framebuffer |
|
||
| Compositor | **Schcom** | SchOS's own compositor — v0 runs; the installer's GUI first, a desktop (**SchDE**) later |
|
||
| Crash screen | **PSOGM / GMMOS** | The Purple Screen of Guru Meditation, and the micro OS that runs under it |
|
||
| API | **SchAPI** | The long-term native interface — *designed, not built* |
|
||
|
||
`uname -s` reports `SchIFT`, the way every Unix reports its kernel rather than
|
||
its distribution.
|
||
|
||
## What works
|
||
|
||
**Kernel** — Long mode, 4-level paging, preemptive multitasking, a fair-share
|
||
scheduler with `nice`. **SMP** up to 64 processors, enumerated from the ACPI
|
||
MADT. **Threads** (`clone`, `futex`, TLB shootdowns), **demand paging** for the
|
||
huge reservations browsers make, and dynamic linking. ACPI through
|
||
[uACPI](https://github.com/uACPI/uACPI): interrupt routing, the power button,
|
||
clean power-off and reset, batteries and AC through a laptop's embedded
|
||
controller, and deep idle states. Memory sized from the firmware's map, up to 256 GB.
|
||
|
||
**Filesystem** — **SchFS** is the root: a copy-on-write B-tree with an uberblock
|
||
ring, so a crash leaves either the old tree or the new one and there is nothing
|
||
to repair. The live image ships as **[SCFF](docs/architecture/scff.md)**: the
|
||
root compresses with zstd to about a third of its size and is unpacked a chunk at
|
||
a time, the first time something reads it. `/proc`, `/sys` and `/dev` are
|
||
synthesised, in Linux's layouts, because that is what the programs read.
|
||
|
||
**Linux software** — `fork`, `clone`, `exec`, pipes, signals, sessions and job
|
||
control, `mmap`, POSIX and `memfd` shared memory, Unix sockets with descriptor and
|
||
credential passing, `poll`, `epoll`, `eventfd`, `timerfd`, `signalfd`, `inotify`,
|
||
pseudo-terminals. The root is managed by Alpine's **apk**: `ports/alpine/world`
|
||
says what is installed, `world.lock` pins it, and `apk add` fetches more over HTTPS.
|
||
|
||
**Desktop** — **Xorg with Window Maker**, `xterm`, the classic X clients, SDL games
|
||
and the NetSurf browser, on the framebuffer (`/dev/fb0`, Linux fbdev) with input
|
||
as Linux evdev. Twelve virtual terminals, switched with Ctrl+Alt+F1–F12, with X on
|
||
a terminal of its own. Sound through ALSA (over OSS and an AC'97 driver).
|
||
|
||
**Drivers** — written from the specifications, and **Linux's own, unmodified,
|
||
through [LDLS](docs/architecture/ldls.md)**: a `.ko` runs in an ordinary process
|
||
and reaches the hardware through `/dev/pci`, so a crashed driver costs an interface,
|
||
not the machine. The laptop's Realtek NIC is driven that way.
|
||
|
||
| | |
|
||
|---|---|
|
||
| Storage | AHCI (SATA), NVMe, IDE, USB mass storage |
|
||
| Network | Intel e1000, Realtek RTL8139 and r8169 (the latter also as Linux's driver in a process) |
|
||
| USB | xHCI, hubs, HID keyboards and mice |
|
||
| Input | PS/2, I2C-HID laptop touchpads and keyboards (DesignWare I2C, found through ACPI) |
|
||
| Display | UEFI GOP framebuffer, virtio-gpu, Bochs/stdvga |
|
||
| Audio | AC'97 |
|
||
|
||
**Networking** — ARP, IPv4, ICMP, UDP, TCP and DHCP on lwIP; DNS, `wget` and `curl`
|
||
over **HTTPS**, `ping`, `httpd`, netlink for `getifaddrs`.
|
||
|
||
**When it dies** — PSOGM, the Purple Screen of Guru Meditation: stop code, fault
|
||
address, call chain, and the log as QR codes. Under it runs **GMMOS**, a micro OS with
|
||
its own keyboard drivers, so a dead machine can still show its log, take a few
|
||
commands, and restart or power off.
|
||
|
||
**On real hardware** — booted from a USB stick on an AMD B550 desktop (Ryzen 5
|
||
4600G), an ASUS TUF A15 laptop and an Ivy Bridge HP all-in-one.
|
||
|
||
## Quick start
|
||
|
||
```sh
|
||
make # kernel + UEFI loader + root filesystem
|
||
make qemu # build it and boot it
|
||
make iso # a bootable ISO for VMware or real hardware
|
||
./write.sh sdX # write that ISO to a USB stick (Linux; it checks what it is overwriting)
|
||
```
|
||
|
||
The ISO is a hybrid image: it boots on any UEFI machine from a stick written with
|
||
`write.sh`, `dd if=schos.iso of=/dev/sdX bs=4M`, or Rufus/Etcher in DD mode. **It runs
|
||
from RAM and touches none of the machine's disks.** Log in on the console, and type
|
||
`startx` for the desktop.
|
||
|
||
Builds on **Linux, macOS, FreeBSD/OpenBSD/NetBSD and Windows** (Git Bash). The
|
||
toolchain is clang + lld everywhere — it is a cross-compiler by construction, so
|
||
one LLVM install targets the bare-metal kernel, the 16-bit boot code and musl
|
||
userland from any host; `nix-shell` supplies all of it. See
|
||
**[docs/guides/building.md](docs/guides/building.md)** for prerequisites per platform.
|
||
|
||
## Testing
|
||
|
||
Booting to a prompt proves nothing: a filesystem can mount and still fail the
|
||
first real command, and that has happened here. So the test harness drives the
|
||
serial console and asserts on what comes back.
|
||
|
||
```sh
|
||
tools/windows/bootcheck.ps1 # boot, run real commands, check the answers
|
||
tools/windows/bootcheck.ps1 -Tty -Ps # terminal behaviour, process enumeration
|
||
make schfs-check # SchFS B-tree, object and image suites
|
||
```
|
||
|
||
`bootcheck` is PowerShell because `pwsh` runs on every supported host. Several
|
||
programs in `cmd/` (`socktest`, `memfdtest`, `xready`, …) exist to be run *on* the
|
||
system and report which of their own checks failed. See
|
||
**[docs/guides/testing.md](docs/guides/testing.md)** for what each proves. The numbers at
|
||
the top are measured, not typed: `python3 tools/python/stats.py` rewrites them here
|
||
and on the website.
|
||
|
||
## Layout
|
||
|
||
```
|
||
kernel/ arch/ core/ dev/ drivers/ fs/ net/ proc/ sys/ acpi/ gmmos/ scff/
|
||
fs/schfs/ the filesystem -- same source the host tools compile
|
||
ldls/ the Linux driver layer: the .ko loader, BTF reader, Linux symbols
|
||
include/ kernel and userland headers, by subsystem (arch/ core/ fs/ dev/ ...)
|
||
boot/ uefi/ (PE loader) common/ (shared loader UI)
|
||
lib/ cmd/ first-party userland runtime and programs
|
||
etc/ what the image starts with: schinit's job manifests, motd, ...
|
||
ports/ third-party software built from source; ports/alpine is the apk root
|
||
tools/ windows/ (.ps1) posix/ (.sh) python/ (.py) and .c/.pl
|
||
projects/ things that run ON SchOS (an installer, SchFS for Linux: both frozen)
|
||
docs/ architecture/ (what it is) plan/ (what's next)
|
||
guides/ (how to work on it) history/ (why it's like this)
|
||
Website/ (the site, and the docs reader)
|
||
```
|
||
|
||
**[docs/README.md](docs/README.md)** is the index. If you are reading the tree
|
||
for the first time, [docs/architecture/README.md](docs/architecture/README.md)
|
||
is the system layer by layer, and [docs/plan/1.0.md](docs/plan/1.0.md) says
|
||
where it stands against its finish line.
|
||
|
||
One rule worth knowing: **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 — found and fixed on the host, where a
|
||
test takes a second instead of a boot.
|
||
|
||
Another: **syscalls are declared in exactly one place**,
|
||
`kernel/sys/table.inc`. Everything else is generated from it.
|
||
|
||
## Not there yet
|
||
|
||
- **No installer, and nothing persists.** The live image runs from RAM and
|
||
writes nothing to the machine's disks, so what you install or save is gone at
|
||
reboot. This is the one thing between the system and its 1.0 definition.
|
||
- **No GPU acceleration.** Xorg draws in software; the plan is Linux's `amdgpu`
|
||
through LDLS ([docs/plan/gpu.md](docs/plan/gpu.md)). There is no IOMMU either,
|
||
so a driver in a process is isolated against its bugs, not against malice.
|
||
- **No udev.** Xorg is told its input devices by a config file instead of
|
||
finding them; `/sys` has no device tree and no uevent socket.
|
||
- **WebKit browsers do not start.** NetSurf does; Epiphany's web process dies at
|
||
start-up, and it has not been run to ground.
|
||
- **USB 2.0 controllers (EHCI)** have no driver. On older machines the ports
|
||
wired only to EHCI do nothing; xHCI ports work.
|
||
- **Touchpads run in mouse mode**: pointer, click and tap, but no two-finger
|
||
scroll yet.
|
||
- **No page cache**, so writable `MAP_SHARED` of a file is refused rather than
|
||
faked, and `mprotect` is accepted and ignored (nothing has NX).
|
||
- **No Wi-Fi, no HDA audio**, and the Realtek NIC on the laptop has reached the
|
||
point of finding its PHY; whether it carries traffic there is not confirmed.
|
||
- SchFS has no Linux driver yet; the plan is on-disk format version first, then
|
||
FUSE, then a kernel module.
|
||
- CFF/OpenType outlines and TrueType hinting are deliberately out of scope.
|
||
|
||
## Licensing
|
||
|
||
**GPL-2.0-or-later**, copyright Nexoniarz. See [LICENSE](LICENSE).
|
||
|
||
The kernel derives from xv6, which is MIT — see [LICENSE.MIT](LICENSE.MIT).
|
||
Third-party code redistributed in a built image (musl, toybox, mksh, zstd, the
|
||
fonts, and Alpine's packages, each under its own licence) keeps that licence;
|
||
[NOTICE](NOTICE) carries the attributions. See [docs/licensing.md](docs/licensing.md).
|
||
|
||
Drivers may be adapted from BSD sources and, since the move to the GPL, from
|
||
Linux — GPL-2.0-only code combines with GPL-2.0-or-later, and the result ships
|
||
under GPLv2. Linux's own drivers run unmodified through LDLS, and the ISO ships the
|
||
Realtek `r8169` set and its firmware; their licences and source are in [NOTICE](NOTICE). Best of
|
||
all is still the public specification — xHCI, virtio, AHCI, e1000 — which carries
|
||
no licence on what you write from it.
|
||
|
||
---
|
||
|
||
<div align="center">
|
||
<sub>Built with stubbornness and a serial console.</sub>
|
||
</div>
|