Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
12 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 diskbuilds (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/dridevice 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_opsspecifies and no driver implements; the same plan. - CFF/Type 2 charstrings, so OTF fonts work. A separate
font_opsprovider and a bytecode interpreter, not an extension of theglyfpath. - 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 needsnl80211, a firmware loader that exists, and a supplicant (wpa_supplicantis 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. 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); 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:
- udev — done (udev.md). eudev runs from
schinit, the uevent netlink socket and the/sys/devicestree exist, PCI and USB devices are in it withadd/removeevents from USB hot-plug, devtmpfs takes udev's links, and Xorg finds its keyboard and mouse through it. Left: USB interfaces, PCI bridges as parents,hwdb. - libinput and libseat — done.
libinput list-devicessees the keyboard and the pointer as an ordinary user, Xorg now drives both throughxf86-input-libinput, andseatdruns fromschinit: a non-root program opensseat0throughlibseat, is handed/dev/input/event0over the socket, and reads it. Getting there found a real kernel bug (sockets returned byaccept()could not carry file descriptors) and a second one insendmsg's control-buffer parsing; both would have stopped a Wayland compositor and its clients too. Not yet tried: a compositor. - A DRM device. Wayland compositors want
/dev/dri/card0with KMS, and Mesa wantsrenderD128. SchOS has neither: it has/dev/fb0. This is the GPU plan (gpu.md) — Linux's ownamdgpurun by LDLS and/dev/driserved by that process — and, for machines without a real GPU driver, a simple-framebuffer DRM shim (Linux'ssimpledrm, which is a.koLDLS could also host). - 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's register is empty, except where the owner says otherwise.
5b. The boot manager
The loader (boot.md) is now a Niveus-styled window: bevelled keys, wells, Instrument Sans, keyboard and pointer, a list of other systems it finds on the disks and can chain-load, the F8 options (resolution with its "keep this?" confirmation, verbose boot), and real Firmware Setup, Restart and Shut Down.
Still to do:
- boot entries from a file on the ESP (several kernels, command lines, "drivers off", a default and a timeout), instead of the two fixed ways of starting this system
- a SchFS partition as a boot source, not just the volume the loader came from
- an honest failure screen for the loader's own errors (today
die()prints to the console) - the pointer path verified on a real machine; QEMU with OVMF never delivered a USB mouse event to the loader
- light appearance, and a theme read from the ESP
It is its own piece of work in boot/uefi/; the kernel's TrueType rasteriser is not available at that point, which is why the
loader carries a pre-rasterised face (include/gfx/nvfont.h).
The installer and .sip
Scoped in projects/schinst/README.md, which holds the detail. In short:
.sipformat specification, written down before any codetools/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
.sipread-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); 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_SHAREDof a file needs.memfdis the narrow answer and has been enough. - A working
mprotect, and NX.mprotectis 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_UNIXsocket 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_stimeis not zero. - A contiguous multi-page allocator, so
struct procandstruct socketcan 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/drifrom a process.
Unfinished, as of 2026-10-26
Left where it stood; none of it is hidden by the code.
startxas root fails. The image now has only root, and in QEMUstartxends withxinit: unable to connect to X server: Bad file descriptorand writes/var/log/Xorg.0.log(not~/.local/share/xorg/). It worked as the oldschosuser. The cause has not been looked at; start with that log.- Window Maker on the laptop hung (no cursor movement, no exit, no VT
switch) while Xorg was using
xf86-input-libinput. That package is out of the image again; whether Xorg's own evdev driver is enough on that machine is not confirmed. If it still hangs, theXorg.0.logfrom the machine is what is needed. - ldlsd's crash on real hardware was a misaligned
movapsin a variadic function; LDLS guest code is now built with-mstackrealign. Not run on the laptop since. TwoSchOS: permission denied (write)lines appear just before it; the message now names the process and inode so the next log says who. - Boot manager pointer: the cursor is drawn whenever a pointer device exists, but no click or movement has been seen from a real device (QEMU's USB mouse never reached the loader). A laptop touchpad is usually not exposed to UEFI at all.
- Kernel-side splash: the loader's splash is in the new style; what vgpud draws once the kernel is up is still the old mark.
- USB: no
/dev/bus/usb(usbfs), so libusb tools such as plainlsusbdo not work (lsusb -tdoes);uname -rsays0.1.0, which libusb refuses; hub port counts and string descriptors are missing. - Terminals: all twelve ask for a login. There is no longer a login-free
root shell to fall back on if
loginitself breaks.