docs: README, plan, guides and the site describe what is built now
README: rewritten around what runs (Linux software, Xorg, apk, Linux's drivers), the honest gaps, measured numbers. plan/: 1.0.md is the finish line, where each clause of the acceptance test stands, and the register (one failing clause: a root that survives a reboot); built plans (foundations, hybrid, alpine, xorg) and the decided-against one (wayland) are gone, their content lives in architecture/; roadmap.md is only what is still open. guides: building/layout/testing/adding-a-driver (Linux code may be used). history: four entries (ls -lR, TLB shootdowns, MDIO 0x02460246, netlink MSG_TRUNC). Website: cards, stack, download page, docs index. Code comments that pointed at deleted plan docs point at the architecture docs. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
This commit is contained in:
parent
2556a955b3
commit
cb3d28e3d6
57 changed files with 685 additions and 2121 deletions
|
|
@ -14,47 +14,46 @@ deliberately kept out of `clean`).
|
|||
schos/
|
||||
├─ boot/ uefi/ the PE/COFF loader (splash, F8 menu, kernel load),
|
||||
│ common/ the UI it shares. UEFI only -- there is no BIOS path.
|
||||
├─ kernel/ The kernel, by subsystem: arch/ core/ dev/ fs/ proc/ sys/
|
||||
├─ kernel/ The kernel, by subsystem: arch/ core/ dev/ drivers/ fs/ net/
|
||||
│ proc/ sys/ acpi/ (uACPI glue, the EC, I2C-HID) gmmos/ (the
|
||||
│ micro OS under the crash screen) scff/ (the decompressor).
|
||||
│ drivers/ is the in-kernel drivers, by class: audio bus gpu
|
||||
│ net storage usb.
|
||||
├─ ldls/ The Linux driver layer: the .ko loader, the BTF reader, the
|
||||
│ Linux symbols reimplemented (kpi/), and host-side test tools.
|
||||
│ The process that runs it is cmd/ldlsd.
|
||||
├─ include/ Headers shared by kernel, userland, and tools/mkfs, by
|
||||
│ subsystem -- see "include/" below
|
||||
├─ lib/ First-party userland runtime: _start glue, syscall stubs,
|
||||
│ the initcode blob embedded in the kernel, user.ld
|
||||
├─ cmd/ First-party programs — one directory per program:
|
||||
│ cmd/<name>/main.c → sysroot/bin/<name>
|
||||
│ schinit and schinitd are PID 1 and its supervisor; vgpud is
|
||||
│ the virtio-gpu driver, which runs out here rather than in
|
||||
│ the kernel; socktest/shmtest/nettest/pcitest are suites.
|
||||
├─ ports/ Third-party software — one directory per port.
|
||||
│ Contains ONLY a Makefile and optional patches/.
|
||||
├─ projects/ Things that run ON SchOS rather than things that ARE it:
|
||||
│ the compositor, window manager, desktop, and installer.
|
||||
│ schinit and schinitd are PID 1 and its supervisor; vgpud and
|
||||
│ ldlsd are drivers that run out here rather than in the
|
||||
│ kernel; socktest/shmtest/nettest/pcitest/xready are suites.
|
||||
├─ etc/ The configuration the image starts with: schinit's job
|
||||
│ manifests (etc/schinit/*.job), motd, os-release, the zsh files.
|
||||
├─ ports/ Third-party software -- one directory per port, containing
|
||||
│ ONLY a Makefile and optional patches/. musl, toybox, mksh,
|
||||
│ lwIP, uACPI, zstd, ncurses, the fonts, fastfetch, kilo; and
|
||||
│ alpine/, which is the apk root (world, world.lock).
|
||||
├─ projects/ Things that run ON SchOS rather than things that ARE it.
|
||||
│ Not part of the kernel build. See projects/README.md.
|
||||
├─ tools/ Host-side helpers, SOURCE ONLY: mkfs.c, the SchFS test
|
||||
│ suites, sign.pl, vectors.pl, and the PowerShell harnesses.
|
||||
│ Their binaries build into build/tools/ -- this directory
|
||||
│ used to hold both, which is the one rule this layout has.
|
||||
│ tools/windows/loc.ps1 counts how much of the tree is first-party.
|
||||
├─ sysroot/ Staging for the disk image. etc/ is hand-maintained;
|
||||
│ bin/ lib/ sbin/ are populated by `make sysroot-install`.
|
||||
├─ dist/ Upstream tarball cache. Survives `make clean`.
|
||||
├─ Refrence/ A FreeBSD checkout (Refrence/freebsd-src), kept as reference
|
||||
│ material and a parts bin. Never built, never in an image.
|
||||
│ Read it when a specification is ambiguous; copy from it only
|
||||
│ after the per-file licence check in docs/licensing.md.
|
||||
│ A full clone is 2.1 GB and a previous NetBSD one was deleted
|
||||
│ for that reason. Only sys/dev, sys/net and sys/netinet have
|
||||
│ ever been read, so a sparse checkout is ~100 MB:
|
||||
│ git clone --filter=blob:none --sparse <url> Refrence/freebsd-src
|
||||
│ git -C Refrence/freebsd-src sparse-checkout set │ sys/dev sys/net sys/netinet
|
||||
├─ src-trunk/ A NetBSD checkout, when present -- reference material and a
|
||||
│ parts bin. NOT built, NOT installed, must never reach an
|
||||
│ image. Currently absent; it was deleted for disk space and
|
||||
│ can be re-fetched sparsely. Copying from it is governed by
|
||||
│ the per-file licence check in docs/licensing.md §3 --
|
||||
│ NetBSD is not uniformly licensed.
|
||||
├─ tools/ Host-side helpers, SOURCE ONLY: mkfs.c, mkschfs.c, mkscff.c,
|
||||
│ the SchFS test suites, vectors.pl, and the harnesses, grouped
|
||||
│ by what runs them (windows/ .ps1, posix/ .sh, python/ .py).
|
||||
│ Their binaries build into build/tools/. tools/windows/loc.ps1
|
||||
│ and tools/python/stats.py count how much of the tree is
|
||||
│ first-party.
|
||||
├─ sysroot/ Staging for the disk image, GENERATED by the build -- edit
|
||||
│ tools/posix/mkaroot.sh and etc/, not this.
|
||||
├─ dist/ Upstream tarball and package cache. Survives `make clean`.
|
||||
├─ shell.nix NixOS development shell: the whole toolchain in one file
|
||||
├─ write.sh Writes schos.iso to a USB stick, safely (Linux).
|
||||
├─ run.ps1 The Windows-side QEMU launcher.
|
||||
├─ docs/ architecture/ what it is plan/ what's next
|
||||
│ guides/ how to work history/ why it's like this
|
||||
│ Website/ the site, and the docs reader that renders this
|
||||
└─ build/ ALL generated output (see below)
|
||||
```
|
||||
|
||||
|
|
@ -92,7 +91,10 @@ build/
|
|||
├─ kernel/ object files, the linked kernel, kernel.asm
|
||||
├─ lib/ libc glue objects, initcode blob
|
||||
├─ cmd/ linked first-party programs
|
||||
├─ fs.img the filesystem image
|
||||
├─ aroot/ the apk root the image is made from
|
||||
├─ schfs.img the root as a disk image (make qemu)
|
||||
├─ fs-ram.img the same root as the live ramdisk, fs-ram.scff compressed
|
||||
├─ iso/ … what make iso assembles
|
||||
└─ ports/<name>/
|
||||
├─ src/ extracted upstream tarball
|
||||
├─ obj/ out-of-tree build directory
|
||||
|
|
@ -130,57 +132,43 @@ Local modifications to upstream go in `ports/foo/patches/*.patch` and are
|
|||
applied after extraction — never by editing files under `build/`, which are
|
||||
wiped on every clean.
|
||||
|
||||
## Ramdisk root
|
||||
## The live root
|
||||
|
||||
```sh
|
||||
make # normal: root on the IDE disk (build/fs.img as hdb)
|
||||
make ramroot # root from a SCHFS image linked into the kernel
|
||||
make # normal: the root is a SchFS disk image, build/schfs.img
|
||||
make iso # the same root as a compressed ramdisk linked into the kernel
|
||||
make ramroot # the ramdisk, uncompressed
|
||||
```
|
||||
|
||||
`make ramroot` builds `build/fs-ram.img` (default 6000 blocks, override with
|
||||
`RAMDISK_BLOCKS=`) and links it into the kernel, so the system boots to a shell
|
||||
with **no data disk attached at all**. That is what makes destructive work on
|
||||
the real disk survivable — reformatting it, or bringing up a new on-disk format
|
||||
— and it is the first piece of the installer.
|
||||
`make iso` builds the root as a SchFS image, compresses it
|
||||
([SCFF](../architecture/scff.md)) and links it into the kernel, so the system boots
|
||||
to a shell with **no data disk attached at all** -- which is what the USB stick is.
|
||||
It is also what makes destructive work on a real disk survivable. Nothing written
|
||||
to a live root survives a reboot.
|
||||
|
||||
Use `make ramroot`, not `make RAMROOT=1`: the flag changes `CFLAGS`, which make
|
||||
cannot see, so objects compiled for one setting would be silently reused for
|
||||
the other and `ROOTDEV` would point at the wrong device. The target drops the
|
||||
compiled objects first. Switching back is the same — plain `make` after a
|
||||
`ramroot` build reuses stale objects, so run `rm -rf build/kernel build/lib
|
||||
build/cmd` first (or just `make clean`).
|
||||
|
||||
The image costs boot time: the loader reads the kernel through the firmware's
|
||||
file protocol, so a 6 MB ramroot kernel is visibly slower to start than the
|
||||
350 KB default.
|
||||
Use the targets, not `make RAMROOT=1`: the flag changes `CFLAGS`, which make cannot
|
||||
see, so objects compiled for one setting would be silently reused for the other and
|
||||
`ROOTDEV` would point at the wrong device. The targets drop the compiled objects
|
||||
first. Going back to the disk root is the same -- run `make clean` or remove
|
||||
`build/kernel build/lib build/cmd` first.
|
||||
|
||||
**What may go in it is a licensing question, not only a size one.** The image is
|
||||
linked into the kernel binary, so anything in `sysroot/` when it is built becomes
|
||||
part of a distributable artifact. A file staged there under a licence that
|
||||
is not ours to redistribute does not merely ride along — it makes the kernel
|
||||
itself undistributable. `RAMDISK_EXCLUDE` in the Makefile is the list of
|
||||
paths kept out, and enforcing it in the build rather than relying on someone
|
||||
remembering to unstage something first is deliberate. It has been needed once
|
||||
already: a 33 MB test payload landed in `sysroot/` and both overflowed the image
|
||||
and would have gone into the kernel binary.
|
||||
part of a distributable artifact. A file staged there under a licence that is not
|
||||
ours to redistribute does not merely ride along -- it makes the kernel itself
|
||||
undistributable. `RAMDISK_EXCLUDE` in the Makefile is the list of paths kept out,
|
||||
and enforcing it in the build rather than relying on someone remembering to unstage
|
||||
something first is deliberate. (Linux modules for LDLS are staged by `make
|
||||
ldls-stage`/`ldls-r8169` only on request, and `.gitignore` refuses `*.ko`.)
|
||||
|
||||
Three knobs, all in the Makefile, none of them `FSSIZE`:
|
||||
The knobs: `RAMDISK_BLOCKS` (image size), `RAMDISK_NINODES` (the inode table is
|
||||
*preallocated*: the default of 12000 once cost a quarter of a small image to
|
||||
describe about 260 files), `RAMDISK_EXCLUDE`. If `mkfs` reports the image is full,
|
||||
read its message: it prints the metadata breakdown and names the right knob.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `RAMDISK_BLOCKS` | image size, 6000 (× 1 KiB `BSIZE`) |
|
||||
| `RAMDISK_NINODES` | inode table size, 2000 |
|
||||
| `RAMDISK_EXCLUDE` | sysroot-relative paths to omit, with their subtrees |
|
||||
|
||||
`RAMDISK_NINODES` is worth knowing about because the inode table is
|
||||
*preallocated*: mkfs's default of 12000 inodes cost 1501 of the 6000 blocks — a
|
||||
quarter of the image — to describe about 260 files. At 2000 it costs 251, and
|
||||
metadata overall fell from 1596 blocks to 345.
|
||||
|
||||
If `mkfs` reports the image is full, read its message: it now prints the
|
||||
metadata breakdown and names the right knob for whichever image overflowed. It
|
||||
used to say only "increase FSSIZE in param.h", which is a constant that has
|
||||
nothing to do with the ramdisk root and sends you to the wrong file.
|
||||
The ISO build is fast on purpose (a few seconds when little changed): it copies with
|
||||
`cp -p` and `install -C` so unchanged files keep their time stamps, and toggling the
|
||||
ramdisk does not wipe the tree.
|
||||
|
||||
## Two things that will bite you
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue