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

@ -5,7 +5,7 @@
// it is an assertion that exactly that much exists. Boot a machine with less
// and kinit1() walks off the end of RAM into nothing; boot one with more and
// every byte above 224 MB is invisible. Measured before this file existed:
// Schunix booted at 224 MB and triple faulted at 192 MB, for no reason at all.
// SchOS booted at 224 MB and triple faulted at 192 MB, for no reason at all.
//
// The firmware has known the answer the whole time. boot/stage2.S asks it with
// INT 0x15 / E820 in real mode -- the same interface Linux's boot stub and GRUB
@ -92,7 +92,7 @@ e820_init(void)
// Below this the kernel image, its page tables and the DMA arena do not fit,
// and continuing produces a failure much harder to read than this line.
if (top < PHYSTOP_MIN) {
cprintf("e820: only %d MB usable; Schunix needs at least %d MB\n",
cprintf("e820: only %d MB usable; SchOS needs at least %d MB\n",
(int)(top / (1024 * 1024)), (int)(PHYSTOP_MIN / (1024 * 1024)));
// Left at the fallback deliberately rather than lowered: a machine this
// small is going to fail, and it should fail having said why.

View file

@ -142,7 +142,7 @@ seginit(void)
// and SS from +8, so the *slot* must exist to keep the
// [UCODE32, UDATA, UCODE] triple consecutive. See syscallinit.
// SEG_KCPU is a leftover slot number from 32-bit xv6, where %gs held the
// per-CPU pointer. Schunix uses FS_BASE/TLS instead, but the
// per-CPU pointer. SchOS uses FS_BASE/TLS instead, but the
// index has to stay occupied or SEG_TSS stops landing at 7.
//
// Deleting either moves every descriptor after it and breaks sysret.

View file

@ -13,7 +13,7 @@ static void mpmain(void) __attribute__((noreturn));
extern char end[]; // first address after kernel loaded from ELF file
// Set by stage2main.c (boot/stage2main.c, BOOT_VERBOSE_FLAG_ADDR) when the
// user picks "Boot Schunix (verbose)" from the F8 boot menu; read once here,
// user picks "Boot SchOS (verbose)" from the F8 boot menu; read once here,
// before anything else, so subsystem init can log its own steps.
int boot_verbose;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
//
// PSOGM — the Schunix crash screen.
// PSOGM — the SchOS crash screen.
//
// The name is a nod to the Amiga's "Guru Meditation", but nothing else about
// this is a nod to 1985. Three things it is built around:
@ -439,7 +439,7 @@ paint(char *reason, addr_t *pcs, int npcs)
// Left-aligned, not centred. Centred text reads as a poster; this is a
// report, and a report is read down the left edge.
vga_text_at(left, y, "Schunix ran into a problem and needs to restart.",
vga_text_at(left, y, "SchOS ran into a problem and needs to restart.",
PSOGM_FG);
y += ch + ch / 2;
vga_text_at(left, y, "Nothing on your disks was touched by this.",
@ -492,7 +492,7 @@ report_serial(char *reason, addr_t *pcs, int npcs)
{
cprintf("\n");
cprintf(" :(\n\n");
cprintf(" Schunix ran into a problem and needs to restart.\n");
cprintf(" SchOS ran into a problem and needs to restart.\n");
cprintf(" PSOGM -- Purple Screen of Guru Meditation\n\n");
for (int i = 0; i < nfields; i++) {

View file

@ -3,7 +3,7 @@
// The kernel has always known how long it had been running -- `ticks`, bumped
// 100 times a second by the timer interrupt -- and has never known what time it
// was. sys_gettimeofday() returned `ticks / 100` as though it were seconds
// since the epoch, so every Schunix machine believed it was the 1st of January
// since the epoch, so every SchOS machine believed it was the 1st of January
// 1970 and that the date advanced at the rate of its own uptime. `date` printed
// a number that barely moved, which is what it looks like when a clock is
// counting from the wrong place rather than not counting at all.

View file

@ -281,7 +281,7 @@ text_selftest(void)
int line = f->ops->height(f) + 6;
int y = 80;
text_draw(&s, f, 60, y + base, "Schunix text rendering", SCH_FG);
text_draw(&s, f, 60, y + base, "SchOS text rendering", SCH_FG);
y += line * 2;
// Deliberately not on a multiple of eight. On the old console this string

View file

@ -179,7 +179,7 @@ fb_ioctl(int request, addr_t arg)
if (!f)
return -EFAULT;
memset(f, 0, sizeof(*f));
safestrcpy(f->id, "schunixfb", sizeof(f->id));
safestrcpy(f->id, "schosfb", sizeof(f->id));
f->smem_start = (unsigned long)vga_fb_phys();
f->smem_len = (unsigned int)vga_fb_size();
f->type = FB_TYPE_PACKED_PIXELS;

View file

@ -143,7 +143,7 @@ gen_cpuinfo(struct sbuf *sb)
// otherwise be told a VM with four processors has four to schedule on, when
// three of them are enumerated and idle. "cpu cores" stays the present count,
// which is what that field means.
// Real values, from CPUID. These used to read "Schunix" and "Schunix virtual
// Real values, from CPUID. These used to read "SchOS" and "SchOS virtual
// CPU" -- a thing to print when you have not asked the processor, and
// actively unhelpful, because identifying the machine is the one question
// /proc/cpuinfo exists to answer.
@ -204,7 +204,8 @@ gen_cpuinfo(struct sbuf *sb)
static void
gen_version(struct sbuf *sb)
{
sb_puts(sb, "Schunix version 0.1.0 (schunix) #1 SMP x86_64\n");
// The kernel's name, not the system's -- same as "Linux version 6.x" here.
sb_puts(sb, "SchIFT version 0.1.0 (schift) #1 SMP x86_64\n");
}
static void

View file

@ -200,7 +200,7 @@ load_outline(struct ttf *f, int gid, struct outline *o)
// A negative contour count means a composite: the glyph is other glyphs
// placed at offsets. This is not an exotic case to skip -- `i` is built from
// a dotless i plus the dot, so skipping composites loses a letter from
// "Schunix", which is exactly how the gap was found.
// "SchOS", which is exactly how the gap was found.
//
// Only the translated case is handled: components with a scale or a 2x2
// matrix are rare outside of synthesised obliques, and applying a transform

View file

@ -41,7 +41,7 @@ uartearlyinit(void)
// Announce that we're here.
for(p="Schunix UART...\n"; *p; p++)
for(p="SchOS UART...\n"; *p; p++)
uartputc(*p);
}

View file

@ -11,7 +11,7 @@
#include "errno.h"
// Binaries with entry points at 0x100000+ are musl/Linux-ABI.
// Schunix-native binaries (init) are linked at 0x4000.
// SchOS-native binaries (init) are linked at 0x4000.
#define LINUX_ABI_ENTRY_THRESHOLD 0x100000UL
extern int linux_syscall_map[];
extern int linux_syscall_map_size;
@ -158,7 +158,7 @@ exec(char *path, char **argv)
}
// Auto-select syscall ABI: musl binaries have entry >= 0x100000;
// Schunix-native binaries (init) are linked at 0x4000.
// SchOS-native binaries (init) are linked at 0x4000.
if (elf.entry >= LINUX_ABI_ENTRY_THRESHOLD) {
myproc()->syscall_map = linux_syscall_map;
myproc()->map_size = linux_syscall_map_size;

View file

@ -152,7 +152,7 @@ fileread(struct file *f, char *addr, int n)
}
if((f->ip->rwmode & 2) == 0){
cprintf("Schunix: permission denied (read)\n");
cprintf("SchOS: permission denied (read)\n");
iunlock(f->ip);
return -1;
}
@ -208,7 +208,7 @@ filewrite(struct file *f, char *addr, int n)
}
if((f->ip->rwmode & 1) == 0){
cprintf("Schunix: permission denied (write)\n");
cprintf("SchOS: permission denied (write)\n");
iunlock(f->ip);
return -1;
}

View file

@ -133,7 +133,7 @@ static void sbputi(struct sb *s, int64 v)
// Linux's /proc/<pid>/stat, as far as anything here reads it.
//
// The field order is not negotiable: ps counts fields by position, so a
// missing one silently shifts everything after it. Fields Schunix does not
// missing one silently shifts everything after it. Fields SchOS does not
// track are zero, which is what Linux itself reports for things a given
// process has never done.
static char

View file

@ -532,7 +532,7 @@ schfs_kroot(void)
/* Phase 2 has no VFS integration -- SchFS files are not reachable */
/* through open(2) yet -- so this is how the mount is observable from */
/* userland at all. It reports the volume and lists the root directory, */
/* which is enough to confirm from inside a running Schunix that the */
/* which is enough to confirm from inside a running SchOS that the */
/* kernel really did parse an image mkschfs wrote. */
/* ------------------------------------------------------------------ */

View file

@ -1,5 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
// Linux x86_64 syscall number -> Schunix syscall number translation.
// Linux x86_64 syscall number -> SchOS syscall number translation.
// Enabled per process by sys_enable_linux_abi (see kernel/sys/sys_compat.c).
//
// This file used to be the second half of a two-place registration scheme: a
@ -16,7 +16,7 @@
#define LINUX_NSYSCALL NSYSCALLS
// Index: Linux x86_64 syscall number. Value: Schunix SYS_* number, or 0 for
// Index: Linux x86_64 syscall number. Value: SchOS SYS_* number, or 0 for
// "not implemented" (syscall() then returns -ENOSYS).
//
// Syscalls declared NO_LINUX in table.inc all land on the single scratch index

View file

@ -114,8 +114,8 @@ sys_uname(void)
struct utsname *u = (struct utsname*)user_ptr(ubuf, sizeof(*u));
if (!u) return -EFAULT;
memset(u, 0, sizeof(*u));
memmove(u->sysname, "Schunix", 8);
memmove(u->nodename, "schunix", 8);
memmove(u->sysname, "SchIFT", 7);
memmove(u->nodename, "schos", 6);
memmove(u->release, "0.1.0", 6);
memmove(u->version, "#1", 3);
memmove(u->machine, "x86_64", 7);

View file

@ -18,7 +18,7 @@
// -----------------------------------------------------------------------
// Linux-ABI-compatible struct stat (x86_64 "struct stat" from
// musl 1.2.5 bits/stat.h) — musl/toybox/dash parse st_mode directly
// out of this exact byte layout, which bears no resemblance to Schunix's
// out of this exact byte layout, which bears no resemblance to SchOS's
// own native `struct stat` (stat.h). Without this, every Linux-ABI process
// reading stat() results (e.g. ls checking S_ISDIR to decide whether to
// list a directory or just print its name) gets garbage.
@ -825,7 +825,7 @@ sys_getdents64(void)
}
// -----------------------------------------------------------------------
// Custom SchunixFS ops
// Custom SchOSFS ops
// -----------------------------------------------------------------------
addr_t sys_delete(void)

View file

@ -1,7 +1,7 @@
// Segregated Kernel -- central syscall table. ONE line per syscall.
//
// Format: SYSCALL(nr, linux_nr, name)
// nr Schunix native syscall number
// nr SchOS native syscall number
// linux_nr Linux x86_64 syscall number, or NO_LINUX if none
// name implemented as sys_<name>() in kernel/sys/sys_*.c
//
@ -120,7 +120,7 @@ SYSCALL( 60, 16, ioctl)
// translation answered "bad syscall" before the stub could answer ENOSYS.
// Now that they do something they need the numbers programs actually use.
//
// `shutdown` is deliberately not the name here: Schunix already has a native
// `shutdown` is deliberately not the name here: SchOS already has a native
// shutdown() that powers the machine off (syscall 32), and two syscalls
// cannot share a sys_ function name. Linux 48 maps to sockshutdown instead.
SYSCALL( 40, 41, socket)