Rename Schunix to SchOS; the kernel becomes SchIFT

Removes the "-unix" element and with it any trademark exposure to The
Open Group.

The split follows the ecosystem layout: SchOS is the system, and the
kernel has its own name. Kernel-identity strings are the only places
that take SchIFT -- uname(2) sysname, /proc/version, and the two licence
sentences that say "kernel" outright. That is what every Unix does here:
`uname -s` on Linux reports the kernel, not the distribution. Everything
a user reads as the product -- panic screen, boot menu, error prefixes,
docs, LICENSE, NOTICE -- is SchOS.

schunix.img is schos.img, the logo assets and the musl TLS patch are
renamed, and __SCHUNIX__ is __SCHOS__ (the define and the patch that
consumes it moved together).

Two things the rename broke, both found by the bootcheck suite:

  - shmtest wrote "SCHUNIX-MMAP-OK" with a hardcoded length of 15 and
    compared it back by hand-counted offsets (m[3]=='U', m[14]=='K').
    The shorter marker left the write running two bytes past the literal
    and the compare reading past the data, failing a file-backed mmap
    that was working correctly. Now written and compared through one
    constant with sizeof.
  - bootcheck asserted a 31-byte file after appending to
    "hello-from-schunix"; the shorter string makes it 29.

Both are the same mistake: a string literal whose length is written out
somewhere else. Full suite green -- base, Tty, Ps, Sock, Fb, Usb, Evdev.
This commit is contained in:
Nexoniarz 2026-08-09 14:09:59 +02:00
commit e04ca28812
83 changed files with 520 additions and 601 deletions

View file

@ -77,7 +77,7 @@ Bringing in toybox (see "Coreutils" below) surfaced four more, all fixed:
all (`kernel/sys/linux_abi.c`) — every external command spawn from a
program that prefers `vfork()` over `fork()` failed outright. Mapped to
the existing `fork()` (a fully correct, if slightly slower, substitute).
- `sys_stat`/`fstat`/`fstatat` (`kernel/sys/sys_fs.c`) filled in Schunix's
- `sys_stat`/`fstat`/`fstatat` (`kernel/sys/sys_fs.c`) filled in SchOS's
own native `struct stat` layout regardless of the caller — musl/toybox
parse a fixed Linux ABI byte layout instead, so `st_mode` was garbage and
tools like `ls` couldn't tell files from directories, or executables from
@ -110,7 +110,7 @@ programs, pipes, and `ls`/`mkdir`/`grep` without issue.
## 2. Naming standardization
Schunix standardizes on exactly one name per role, regardless of the
SchOS standardizes on exactly one name per role, regardless of the
underlying implementation: the shell is always installed and exec'd as
`/bin/sh` (currently mksh, built from `ports/mksh/`), and PID 1 is always
`/bin/init`. `cmd/init/main.c`'s exec loop only ever tries `/bin/sh` — no
@ -161,7 +161,7 @@ Split into two stages, the standard way real bootloaders solve this:
compiled size, and errors out (like `tools/sign.pl` does for stage 1) if
it ever grows past that budget instead of silently corrupting the layout.
The kernel now starts at disk sector 17 instead of 1 (`schunix.img`'s `dd
The kernel now starts at disk sector 17 instead of 1 (`schos.img`'s `dd
... seek=17` in the root `Makefile`, and the equivalent `+(1+STAGE2_SECTORS)`
in `stage2main.c`'s `readseg()` — all three places that encode
`STAGE2_SECTORS` have to agree, or the kernel won't be found on disk at
@ -184,7 +184,7 @@ renderer in `stage2main.c` (not the kernel's `vga.c` — paging isn't set up
yet, so the LFB physical address from the VBE block is used as a plain
pointer) reusing the kernel's own font data (`include/font.h`) directly.
It fills the framebuffer with PSOGM's purple (matching
`kernel/core/console.c`'s panic screen) and draws "SCHUNIX" centered, then:
`kernel/core/console.c`'s panic screen) and draws "SCHOS" centered, then:
- **Real-time loading bar**: `readsect()` (in `stage2main.c`, not the
kernel) calls `progress_tick()` after every 512-byte disk read, updating
@ -210,7 +210,7 @@ It fills the framebuffer with PSOGM's purple (matching
`sys_reboot()`); a real bootloader can't jump into BIOS/UEFI setup
directly, so this is the closest honest equivalent — it gives the user
a fresh POST during which their firmware's own setup-menu key works.
- **Verbose boot**: picking "Boot Schunix (verbose)" writes a flag byte to
- **Verbose boot**: picking "Boot SchOS (verbose)" writes a flag byte to
`BOOT_VERBOSE_FLAG_ADDR` (`VBE_INFO_ADDR + 0x100`, i.e. just past the VBE
block) before jumping to the kernel. `kernel/core/main.c`'s `kmain()`
reads it into a global `boot_verbose` as its very first action and, if
@ -496,7 +496,7 @@ became an amber terminal. `include/theme.h` is now the one palette, and the
rule is: **normal states are calm and dark; only failure is loud.** PSOGM keeps
the purple entirely to itself, which is what makes it mean something.
The splash copy went from "Schunix Boot Manager / version 1.0 / Memory: 1023 MB
The splash copy went from "SchOS Boot Manager / version 1.0 / Memory: 1023 MB
/ Press F8 for boot menu..." to the product name, a rule in the accent colour,
and the one hint that is actionable — moved to the bottom, where a hint
belongs. No shipping OS names its bootloader on the splash.

View file

@ -1,4 +1,4 @@
# SchAPI, and Schunix as a system
# SchAPI, and SchOS as a system
Status: **direction agreed, not yet implemented.** Nothing in this document
changes what is being built this week; it changes what everything is being
@ -8,7 +8,7 @@ built *towards*. See §7 for what actually happens now.
## 1. The decision
Schunix stops being "a Unix-like kernel with a userland bolted on" and becomes
SchOS stops being "a Unix-like kernel with a userland bolted on" and becomes
a **system**: a kernel, a native API, and the services and applications that
sit on it, designed together.
@ -50,7 +50,7 @@ Linux made the opposite choice — the syscall ABI *is* the contract, "we do not
break userspace" — and consequently every syscall mistake ever made is still
there, with a `2` or a `64` suffixed to the name of its replacement.
So, for Schunix:
So, for SchOS:
```
┌──────────────────────────────────────────────┐
@ -58,7 +58,7 @@ So, for Schunix:
├──────────────────────────────────────────────┤
│ SchAPI │ POSIX / Linux personality│ ← THE STABLE BOUNDARY
├──────────────────┴───────────────────────────┤
│ libschunix — the only thing that may syscall│
│ libschos — the only thing that may syscall│
├──────────────────────────────────────────────┤
│ syscall table — PRIVATE, unstable, renumberable
├──────────────────────────────────────────────┤
@ -69,11 +69,11 @@ So, for Schunix:
Rules that follow, and they are not negotiable if the promise is to hold:
1. **A program that issues `syscall` directly is unsupported.** It may break at
any release. Only `libschunix` may.
2. `libschunix` exports versioned symbols. An entry point's behaviour never
any release. Only `libschos` may.
2. `libschos` exports versioned symbols. An entry point's behaviour never
changes; a changed behaviour is a new version of the symbol.
3. The kernel may renumber, merge, split or delete syscalls at will, provided
`libschunix` still presents the same surface.
`libschos` still presents the same surface.
This *reconciles* with the existing decision to adopt Linux syscall numbering
(`docs/roadmap.md`, and the reason musl/toybox/mksh work at all). Linux
@ -98,7 +98,7 @@ Every public interface carries exactly one tier:
| `provisional` | Until the next release | Freely |
| `internal` | None | Freely, without notice |
**Everything in Schunix today is `provisional`.** The freeze starts at 1.0 and
**Everything in SchOS today is `provisional`.** The freeze starts at 1.0 and
covers only what is marked `stable` at that moment. This is not a way of
dodging the commitment — it is the only way to make it, because a promise made
now would permanently enshrine, among other things, a `fcntl(F_SETFL)` that
@ -164,7 +164,7 @@ reasons that a single tree cannot give:
That table is the same lesson §1 of the roadmap already learned the hard way
with FreeBSD's `sys/dev/usb`: 100k lines welded to newbus, where porting the
USB stack means porting the device framework first. Networking is the same
shape. Read FreeBSD, lift NetBSD, write Schunix.
shape. Read FreeBSD, lift NetBSD, write SchOS.
### Licensing — read this before copying anything
@ -181,7 +181,7 @@ Ranked by value, not by size:
1. **`sys/net`, `sys/netinet` — the TCP/IP stack.** The largest single win
available. Phase 2 of the roadmap wants ARP/IPv4/ICMP/UDP/TCP, and this is a
mature, clean, readable, 2-clause-heavy implementation of exactly that.
2. **`sys/kern/subr_pool.c` — the pool/slab allocator.** Schunix has `kalloc`
2. **`sys/kern/subr_pool.c` — the pool/slab allocator.** SchOS has `kalloc`
and a page at a time. Every subsystem written since has invented its own
fixed-size table to work around that.
3. **`autoconf` — the driver framework** (`config(1)`, `cfdriver`/`cfattach`,
@ -203,7 +203,7 @@ relicensed-in-notice, and maintained forever under the §3 promise.
Not yet designed. What is decided about it:
- It is the native interface; POSIX is available beneath it but not the idiom.
- It is reached through `libschunix`, never by direct syscall.
- It is reached through `libschos`, never by direct syscall.
- It is designed *with* Schcom in mind, because a compositor and its clients
are the first real users and their needs (IPC, shared buffers, event streams,
object lifetimes) are what will shape it.
@ -234,6 +234,6 @@ What this document changes *today* is only this:
something to work with at 1.0.
3. When the network stack is written, NetBSD's is the starting point rather
than a blank file — with the licence check in §5 applied per file.
4. `libschunix` is created when there is a second personality to justify it.
4. `libschos` is created when there is a second personality to justify it.
Until then, the *rule* stands even though the library does not exist yet:
no new first-party program issues raw syscalls.

View file

@ -42,7 +42,7 @@ end to end.
## 2. What is deliberately not taken
- **No ZFS storage pools / RAID-Z / vdevs.** Multi-disk redundancy is a large
subsystem that solves a problem Schunix does not have yet.
subsystem that solves a problem SchOS does not have yet.
- **No btrfs-style rebalancing or online format conversion.** Enormous
complexity, and it is the historical source of btrfs's worst bugs.
- **No actual SQL.** No parser, no query planner, no relational engine. See §6 —
@ -242,7 +242,7 @@ Phases 1-3 are roughly 3,000-4,000 lines and are the bulk of the work. Phase 1
alone (B-tree + torture harness) is worth doing carefully and unhurriedly; every
later phase compounds on it.
This is the largest single piece of work in Schunix. It is also entirely
This is the largest single piece of work in SchOS. It is also entirely
ordinary filesystem engineering with excellent published references
(Giampaolo for BeFS; the btrfs design papers; the ZFS uberblock/checksum-in-
parent scheme) — there is no research risk here, only volume.
@ -254,7 +254,7 @@ populate this format. Building it against v1 means building it twice.
Three different things get called "the limit", and they are worth keeping apart:
what the **on-disk format** can express, what **this implementation** can
currently mount, and what the **rest of Schunix** can carry. The smallest one is
currently mount, and what the **rest of SchOS** can carry. The smallest one is
what you actually hit.
### The format
@ -292,7 +292,7 @@ raising `SCHFS_SPACE_PAGES` to 4096 makes it 512 GiB at 64 KiB of pointers per
mount. It is set where it is because the page-pointer vector lives inside
`struct schfs_vol`, which the kernel holds as static storage.
### The rest of Schunix
### The rest of SchOS
These are VFS and driver limits rather than SchFS ones: