SchOS/docs/plan/roadmap.md
Nexoniarz ed81f9a07a Schcom is gone; the desktop path is Xorg now, Wayland groundwork next
SchOS will not write its own compositor. projects/schcom, its test and its make targets are deleted. roadmap.md section 5 is
now the road to Wayland (udev/eudev, a /sys/devices tree and uevent netlink, libinput and libseat, a DRM device via the GPU
plan) and 5b is the boot manager rework (Niveus/skeuomorphic UEFI GUI). XLibre, Xorg or a Wayland compositor from Alpine,
whichever suits; Xorg for now.

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

159 lines
10 KiB
Markdown

# Roadmap — everything else still open
[1.0.md](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/](../architecture/) and was
rewritten as a description of what it produced — see
[the rule](../README.md#the-rule-that-keeps-this-from-rotting).
---
## 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](../architecture/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](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](../architecture/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. The desktop, and the road to Wayland
SchOS does not write its own compositor. (Schcom, a 715-line v0, was deleted: its wire format was a dead end, and a
compositor worth running is years of work that Alpine already packages.) The desktop is **Xorg with Window Maker** now
([desktop.md](../architecture/desktop.md)); **XLibre**, the Xorg fork, is a drop-in alternative if Alpine carries it, and a
Wayland compositor (labwc, sway, weston, a GNOME or KDE session) is the larger step. What Wayland — and a modern X — need
from the system, in the order they are useful:
1. **udev.** Today Xorg is *told* its input devices (`xorg.conf.d/10-schos.conf`) because nothing announces them. The fix is
Alpine's `eudev` (or `udev`) running on SchOS, which wants: a **uevent netlink socket** (`NETLINK_KOBJECT_UEVENT`, with the
`add`/`remove`/`change` messages and their environment), a real **`/sys/devices` tree** with `/sys/bus/*/devices/*` and
`/sys/class/*/*` as symlinks into it, `uevent` files that can be written to replay events (`udevadm trigger`), and devtmpfs
that udev can create nodes in. libinput then enumerates evdev devices through it.
2. **libinput and libseat** (seatd is in Alpine): evdev with the properties libinput reads (`ID_INPUT_*` from udev), and a way
for a non-root compositor to take the keyboard and the display from the kernel — the `VT_PROCESS` handshake exists.
3. **A DRM device.** Wayland compositors want `/dev/dri/card0` with KMS, and Mesa wants `renderD128`. SchOS has neither: it has
`/dev/fb0`. This is the GPU plan ([gpu.md](gpu.md)) — Linux's own `amdgpu` run by LDLS and `/dev/dri` served by that
process — and, for machines without a real GPU driver, a *simple-framebuffer* DRM shim (Linux's `simpledrm`, which is a
`.ko` LDLS could also host).
4. **dma-buf, `epoll`-able sync files and the rest of the Linux graphics ABI**, as the compositors turn out to need them.
None of this is a kernel rewrite: it is the Linux interfaces that already exist half-built (`/sys`, netlink, evdev, `SCM_RIGHTS`,
`memfd`), finished until real programs stop asking for what is missing. The method is the one that has worked all along: `apk
add` the program, run it, and fix what it names.
Nothing here starts before [1.0.md](1.0.md)'s register is empty, except where the owner says otherwise.
## 5b. The boot manager
The loader ([boot.md](../architecture/boot.md)) is a text menu: a splash, "Press F8", a list of options. UEFI gives much more:
a graphics-output framebuffer at the panel's native mode, a pointer protocol, file systems to read themes from. The plan is a
boot manager that is worth looking at — in the **Niveus / skeuomorphic** style the site and the wallpapers already use (the
Shift mark, real materials, depth) — and usable: a mouse and keyboard, a list of what can be booted (this ISO, a SchFS
partition, other operating systems' loaders), the options that live in the F8 menu now (resolution with its "keep this?"
confirmation, verbose boot, drivers off), and an honest failure screen. It is its own piece of work in `boot/uefi/`
(a small text and image renderer in the loader — the kernel's TrueType rasteriser is not available yet at that point) and it
replaces the boot-time display handling that grew by accretion (GOP mode choice, the "keep this resolution" probe, the font scaling
in the kernel) with one design.
### The installer and `.sip`
Scoped in [`projects/schinst/README.md`](../../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](../architecture/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`.
Its GUI is the boot manager's (5b) — the installation environment starts in it — or an X client.
## 6. SchFS beyond SchOS
In the order they should happen.
**An upgrade step.** The format version policy is done ([schfs.md](../architecture/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](../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.