A 64-bit operating system written from the metal up: SMP kernel, copy-on-write filesystem, Linux syscall ABI, Alpine packages, X11 on real hardware.
  • C 90.2%
  • Makefile 3.2%
  • PowerShell 2.3%
  • Shell 1.7%
  • Python 1.3%
  • Other 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Nexoniarz 438e7af141 Keyboard lights, TLB shootdowns, battery in sysfs, /proc/pid/maps
Caps, Num and Scroll Lock now light their LEDs on PS/2 and USB keyboards,
share one state between keyboards, and stop toggling on key repeat. X sets
them through evdev writes while it holds the keyboard.

Unmapping memory in a process with threads on other CPUs now flushes their
TLBs with an IPI. Without it a freed page stayed reachable through stale
translations, which corrupted Epiphany's heap on SMP.

ACPI batteries and AC adapters appear under /sys/class/power_supply.
/proc/<pid>/maps lists file mappings, and a process killed by a fault
names the file and offset it died in. r8169 gets a 256-entry RX ring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
2026-10-25 13:43:27 +01:00
.claude/memory include: one folder per subsystem, and includes that name it 2026-10-23 15:05:12 +02:00
boot i2c-hid: the touchpad crash was a printf format, not the driver 2026-10-25 00:28:23 +02:00
cmd Demand paging, the RTL8168H, links that come up late, and Ctrl+Alt+F1..F12 2026-10-25 11:27:48 +01:00
docs Demand paging, the RTL8168H, links that come up late, and Ctrl+Alt+F1..F12 2026-10-25 11:27:48 +01:00
etc X on the console: /dev/tty0, a palette, and startx that works 2026-10-24 19:44:10 +02:00
include Keyboard lights, TLB shootdowns, battery in sysfs, /proc/pid/maps 2026-10-25 13:43:27 +01:00
kernel Keyboard lights, TLB shootdowns, battery in sysfs, /proc/pid/maps 2026-10-25 13:43:27 +01:00
ldls include: one folder per subsystem, and includes that name it 2026-10-23 15:05:12 +02:00
lib include: one folder per subsystem, and includes that name it 2026-10-23 15:05:12 +02:00
ports Sound through ALSA, a 2D game, and a stack walk that cannot panic 2026-10-25 05:39:16 +01:00
projects licence: SchOS is GPL-2.0-or-later, no longer Apache-2.0 2026-10-22 08:48:45 +02:00
srv userland: 268 applets, an editor, names that resolve, and a web server 2026-09-14 19:24:55 +02:00
tools Sound through ALSA, a 2D game, and a stack walk that cannot panic 2026-10-25 05:39:16 +01:00
.gdbinit build: a gdb target, because the tree had no source-level debugger 2026-09-13 15:05:46 +02:00
.gitattributes README: the logo, what works now, and measured numbers 2026-10-24 22:02:44 +02:00
.gitignore licence: SchOS is GPL-2.0-or-later, no longer Apache-2.0 2026-10-22 08:48:45 +02:00
LICENSE licence: SchOS is GPL-2.0-or-later, no longer Apache-2.0 2026-10-22 08:48:45 +02:00
LICENSE.MIT Rename Schunix to SchOS; the kernel becomes SchIFT 2026-08-09 14:09:59 +02:00
Makefile Keyboard lights, TLB shootdowns, battery in sysfs, /proc/pid/maps 2026-10-25 13:43:27 +01:00
NOTICE SCFF: the live root ships compressed, with Xorg and Window Maker 2026-10-24 21:17:31 +02:00
README.md README: the logo, what works now, and measured numbers 2026-10-24 22:02:44 +02:00
run.ps1 boot/uefi: the system information panel, and the offset that faked a version 2026-08-11 10:52:43 +02:00
shell.nix NetSurf: what GTK's images and libcurl's resolver needed 2026-10-25 04:10:26 +01:00
write.sh uefi: copy the kernel home and jump from a page it cannot reach 2026-10-24 11:00:02 +02:00

Shift, the SchOS mark

SchOS

A 64-bit operating system, written from the metal up.

SMP kernel · copy-on-write filesystem · Linux syscall ABI · Alpine packages · X11 on real hardware


SchOS began as xv6 and is now mostly something else. The scheduler, the memory manager and the trap path have been rewritten for x86-64 and for more than one processor; the filesystem has been replaced outright; the syscall table speaks Linux numbering, so real Linux software runs on it unmodified — statically or dynamically linked, straight out of Alpine's package repositories.

It is a hobby system built by one person, and it is honest about that: what works below has been run, not inferred, and the gaps are listed as plainly as the features.

In numbers

First-party code 61,367 lines, plus 21,128 lines of comments (26%) in 272 files
Kernel (kernel/, include/) 45,207 lines of code, 16,111 of comments
Syscalls 208, of which 184 on Linux numbering
Drivers 15 in the kernel
First-party programs 29 in cmd/
Alpine packages in the root 88, from 11 asked for in ports/alpine/world
History 253 commits since 2026-08-09 (76 days)
Lines by language
Language Code Comments
C 56,580 19,427
Assembly 1,750 336
PowerShell 1,362 638
Python 759 147
Shell 716 469
Perl 129 45
Linker script 71 66

Measured by tools/python/stats.py; first-party code only, so ports/ and generated tables are not counted.

The pieces

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
Image format SCFF The SchOS Compressed File Format the live root ships in
API SchAPI System programming interface — the stable surface
Compositor SchCom Display compositor (planned)
Window manager SchWM (planned)
Desktop SchDE (planned)

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. SMP up to 64 processors, enumerated from the ACPI MADT. ACPI through uACPI: interrupt routing from _PRT, the power button, clean power-off and reset. Memory sized from the E820/UEFI map.

Filesystem — SchFS is the root: a copy-on-write B-tree with a 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: the 358 MB root compresses to 102 MB with zstd and is unpacked a chunk at a time, the first time something reads it. /proc has /proc/<pid>/fd, /proc/self and the rest that ps, top and Xorg read.

Processes — fork, exec, wait, pipes, signals, sessions and job control, mmap (anonymous and file-backed), POSIX shared memory, memfd, Unix domain sockets with descriptor passing (SCM_RIGHTS), poll, epoll, eventfd, timerfd, signalfd. Dynamic linking: exec loads ld-musl, so binaries come from Alpine as they are.

Packages — the root is managed by Alpine's apk. ports/alpine/world says what is installed; the build resolves it once into world.lock and every image after that is reproducible. SchOS itself is one more package in it.

Graphics — Xorg with Window Maker, preinstalled, on the framebuffer (/dev/fb0, Linux fbdev). Six virtual terminals, switched with Ctrl+Alt+F1–F6 or Alt+F1–F6, with X on a terminal of its own; Ctrl+Alt+Backspace ends the session. Input as Linux evdev on /dev/input/event*.

Devices — PCI with a bus-agnostic device model at /proc/devices.

Storage AHCI (SATA), NVMe, IDE, USB mass storage
Network Intel e1000, Realtek r8169 and RTL8139
USB xHCI, hubs, HID keyboards and mice
Input PS/2, I2C-HID laptop touchpads (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 over HTTPS, ping, and an httpd serving a directory back.

Userland — musl, toybox, mksh and zsh, plus whatever Alpine has: ls, ps, top, awk, diff, xterm, fastfetch behave the way you expect, because they are the real programs.

Text — a TrueType rasteriser (glyf outlines, composite glyphs, cmap format 4). JetBrains Mono for the terminal, Roboto for the desktop to come.

When it dies — PSOGM, the Purple Screen of Guru Meditation: stop code, fault address, call chain, and a QR code containing a text copy of the whole report.

On real hardware — booted on an AMD B550 desktop (Ryzen 5 4600G), an ASUS TUF A15 laptop and an Ivy Bridge HP all-in-one, from a USB stick.

Quick start

make          # kernel + UEFI loader + root filesystem
make qemu     # build it and boot it
make iso      # a bootable ISO for VMware or real hardware

The ISO is a hybrid image: write it to a USB stick with dd if=schos.iso of=/dev/sdX bs=4M (or Rufus/Etcher in DD mode) and boot it on any UEFI machine.

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. See docs/guides/building.md for prerequisites per platform, and docs/history/moving-to-linux.md for moving a checkout between machines.

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.

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.

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/
  fs/schfs/     the filesystem -- same source the host tools compile
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
ports/      third-party software built from source
tools/      windows/ (.ps1)  posix/ (.sh)  python/ (.py)  and .c/.pl
docs/       architecture/ (what it is)  plan/ (what's next)
            guides/ (how to work on it)  history/ (why it's like this)

docs/README.md is the index. If you are reading the tree for the first time, docs/architecture/README.md is the system layer by layer.

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 threads. clone makes processes, not threads (CLONE_VM is refused), so multi-threaded programs run on one thread or not at all. Xorg runs with -dumbSched for this reason.
  • No udev. Xorg is told its input devices by a config file instead of finding them; /sys and the device-event socket are what is missing.
  • 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. SysV shared memory is missing too.
  • No installer. SchOS runs live from the USB stick; nothing is written to the machine's disks.
  • 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.

The kernel derives from xv6, which is MIT — see LICENSE.MIT. Third-party code redistributed in a built image (musl, toybox, mksh, zsh, kilo, the fonts) keeps its own licence; NOTICE carries the attributions. See 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. Best of all is still the public specification — xHCI, virtio, AHCI, e1000 — which carries no licence on what you write from it.


Built with stubbornness and a serial console.