The F8 menu is redrawn in the Niveus language: a window with three lights, bevelled keys with a lit edge, wells for panels, anti-aliased corners and a soft shadow, set in Instrument Sans rasterised into include/gfx/nvfont.h (tools/python/mknvfont.py, make nvfont). Scale doubles on screens 1400 px tall or more. Lists taller than the screen scroll. The keyboard still drives everything, and a mouse, touchpad or tablet does too: both UEFI pointer protocols are polled, hover moves the highlight, a click activates. The cursor stays hidden until the pointer has really done something, since the firmware installs a pointer protocol with or without a mouse. The 'keep this resolution?' countdown is one ten-second budget however many times the pointer moves. Loaders found at well-known paths on any volume (Windows, Ubuntu, Debian, Fedora, Arch, openSUSE, systemd-boot, rEFInd, other BOOTX64.EFI) are listed and chain-loaded with LoadImage/StartImage. 'Reboot to firmware' used to halt; it now sets OsIndications and restarts, and Restart and Shut Down call ResetSystem. Checked under QEMU+OVMF: menu, resolution list (incl. 2560x1600 at double scale), system information, shut down, firmware setup, chain-loading a copy of the loader from a second disk, and a full boot of the ISO to the login prompt. Pointer hover and click were checked only with synthetic events: in this setup a USB mouse or tablet delivered no event to the loader (one USB I/O handle appeared but no pointer protocol came from it), and why was not established. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
164 lines
10 KiB
Markdown
164 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 — done for the kernel's own devices** ([udev.md](../architecture/udev.md)). eudev runs from `schinit`, the uevent
|
|
netlink socket and the `/sys/devices` tree exist, devtmpfs takes udev's links, and Xorg finds its keyboard and mouse
|
|
through it. **Left:** PCI and USB devices in the same tree, with `add`/`remove` events from the hotplug thread, so a USB
|
|
keyboard or a GPU appears to udev; 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#the-boot-manager)) 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`](../../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.
|