SchOS/docs/plan/roadmap.md
Nexoniarz 59aff881ac docs: 1.0 is reached; Schcom stays; Linux's r8169 set ships
1.0: the acceptance test drops its reboot clause (a live system is the finish line) and passes. Schcom is kept with a
job: the installer's GUI first, SchDE on top later (roadmap section 5). The old 'LDLS ships no Linux code' policy is
gone from ldls/devices/licensing/Makefile/.gitignore/ldlsd; NOTICE records the r8169 modules (GPL-2.0-only) and the
Realtek firmware. The download button points at the v0.1.0 release asset; the stale 64 MB ISO under docs/Website is
removed. mkaroot.sh's -dumbSched comment no longer claims SchOS has no threads.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
2026-10-26 08:23:20 +01:00

8.2 KiB

Roadmap — everything else still open

1.0.md draws the finish line and holds the register of what is half-built. This file holds what is left beyond it: work that is scoped, agreed and unstarted, with nothing in it that is finished.

Finished work is not here. It moved to ../architecture/ and was rewritten as a description of what it produced — see the rule.


1. Storage and the boot path

A USB disk, a SATA disk, an NVMe SSD and their partitions boot, and the root is chosen at boot from what is present (boot.md).

  • An installer that writes the layout make disk builds (a GPT disk with an ESP and a SchFS partition) to a machine's disk, so a root survives a reboot. See §5.
  • Interrupt-driven, queued I/O for AHCI and NVMe. Both poll for completion, one command at a time per disk: enough to boot and run, not to be fast.
  • An EHCI driver. USB 2.0 ports wired only to EHCI do nothing; xHCI ports work.

2. Graphics

  • A /dev/dri device with mode setting, so a real panel's resolution stops being whatever the loader's menu chose and Mesa has something to open. This is the GPU plan, gpu.md.
  • Double buffering and vblank, which display_ops specifies and no driver implements; the same plan.
  • CFF/Type 2 charstrings, so OTF fonts work. A separate font_ops provider and a bytecode interpreter, not an extension of the glyf path.
  • Text layout — advance widths, kerning — as a library, so the terminal and the file manager are not each solving it.

3. Networking

  • A routing table and /proc/net/route. With two interfaces up the first is the default route and the second is reachable only by an address on its own subnet; that is a rule and not routing.
  • Wi-Fi. The laptop has no other way to be wireless. The route is the same as for the NIC: a Linux driver (iwlwifi, mt76…) through LDLS, which needs nl80211, a firmware loader that exists, and a supplicant (wpa_supplicant is an Alpine package).
  • IPv6.
  • A netlink event stream, for anything that wants to be told a link changed.

4. The hardware that makes a laptop a laptop

  • HDA audio. AC'97 is what QEMU and old boards have; a laptop built this century has Intel HDA, which is codec enumeration, CORB/RIRB and stream descriptors. It arrives as a second struct audio_ops.
  • Embedded-controller events (the ACPI SCI), so a lid, a power button on the EC and a battery change are seen.
  • CPU frequency control (AMD CPPC; Intel HWP/EIST). Idle already reaches _CST's C2; under load the cores run at the firmware's default clock.
  • Touchpad gestures — two-finger scroll, palm rejection — on top of I2C-HID's mouse mode.
  • An IOMMU (VT-d / AMD-Vi), which turns "a driver in a process is isolated against bugs" into "against malice" — the largest honest caveat on ldls.md.
  • udev's job — a uevent socket and /sys/devices — so X and others are told about devices instead of being given a list.

5. Schcom, the installer, and SchDE

Schcom (projects/schcom/) is SchOS's own compositor. v0 is 715 lines that composite clients over a wire format of its own, and everything it was blocked on in the kernel now exists: Unix sockets, descriptor passing, memfd, evdev, framebuffer mmap. The plan is in three steps, each useful on its own:

  1. The installer's GUI is Schcom's first real client. An installer wants a window, a list, a progress bar and a handful of input events — small enough to be the program that forces Schcom's protocol to be real, and independent of Xorg, which is not in the installation environment. It needs a wire format for clients that is designed (Wayland-shaped: surfaces, buffers shared by descriptor, input events), not the v0 one.
  2. If that works, Schcom becomes useful in its own right: window management as a module of the compositor (a compositor is its window manager), multiple clients with focus and stacking, damage tracking.
  3. SchDE on top of it: a panel, a launcher, a wallpaper and settings, as ordinary clients — only once there is a Schcom worth putting them on. Until then the desktop is Xorg with Window Maker (desktop.md).

Nothing here starts before 1.0.md's register is empty.

The installer and .sip

Scoped in projects/schinst/README.md, which holds the detail. In short:

  • .sip format specification, written down before any code
  • tools/mksip — capture a directory tree into a package
  • The apply path
  • An installation environment that boots from the ISO, partitions, applies the .sip, and installs the loader

.sip is modelled on WIM, and the thing worth copying from WIM is that it is file-based, not block-based: one file holds a whole filesystem, applies to a partition of any size, and several images can share their common files.

Most of this already exists. tools/mkschfs.c and tools/mkfs.c both do content dedup with an (st_dev, st_ino) fast path, and SchFS's B-tree is content addressed. mksip should share that code rather than reimplement it. And the live image is already a compressed block image of a SchFS root (scff.md); an installer may need nothing more than to write that, decompressed, to a partition.

Open questions, all wanting a decision before code:

  • Compression. Something with a small decompressor is worth more than something with a good ratio, because the decompressor runs in the installation environment. (zstd is already in the kernel for SCFF.)
  • Multiple images per .sip — WIM's real trick, install/recovery/boot sharing one blob store. Worth the complexity now, or not?
  • Can the kernel mount a .sip read-only directly? If it can, the installation environment's root can simply be the .sip.

The GUI for this is a Schcom client (above).

6. SchFS beyond SchOS

In the order they should happen.

An upgrade step. The format version policy is done (schfs.md); the upgrade step cannot be written until there are two formats to convert between, and the first bump is when it becomes real work.

A Linux implementation, FUSE first. Three reasons in order of weight: it can be tested with fsx and xfstests, which are far harsher than anything written alongside the code; it carries no licence entanglement, since libfuse is LGPL and used across a process boundary; and it can reuse the read/write logic already in tools/mkschfs and tools/schfs_fsck rather than being written twice and having the two disagree. A kernel module comes only after FUSE passes xfstests; SchOS is GPL-2.0-or-later (../licensing.md), so a Linux module is a technical project now and not a licensing one.

The missing features, listed honestly before adding any: no journal replay across an unclean shutdown beyond what copy-on-write gives for free, no snapshots, no sparse-file support, and no online fsck. Snapshots are the one where the existing design already pays for most of the cost — the B-tree is copy-on-write, which is most of the machinery; nothing takes or names a snapshot.

7. The kernel's own gaps

Not phases, and each one improves everything above it:

  • A page cache, which is what a general writable MAP_SHARED of a file needs. memfd is the narrow answer and has been enough.
  • A working mprotect, and NX. mprotect is accepted and ignored and every mapping is executable; RELRO, guard pages and a W^X JIT all want the real thing.
  • Per-CPU run queues and work stealing, with a load balancer that is not worse than the lock it replaces.
  • A garbage collector for descriptors in flight. An AF_UNIX socket passed over itself and never received leaks the pair; bounded at thirty-two, and nothing in the tree does it.
  • Kernel-time accounting, so ru_stime is not zero.
  • A contiguous multi-page allocator, so struct proc and struct socket can come from somewhere other than fixed tables.

Kept out of scope on purpose

  • TrueType hinting.
  • DRM/KMS as a kernel subsystem; the GPU plan serves /dev/dri from a process.