SchOS/ports/musl/patches/0001-schos-tls.patch
Nexoniarz e04ca28812 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.
2026-08-09 14:09:59 +02:00

133 lines
4.8 KiB
Diff

From: SchOS Project <kernel@schos.org>
Subject: [PATCH] schos: TLS via global, mallocng decls, optional malloc tracing
Three local changes to musl 1.2.5, kept in one patch because they are all
"make musl work on SchOS" and share a lifetime.
1. arch/x86_64/pthread_arch.h, src/env/__init_tls.c - TLS.
SchOS's kernel saves/restores FS_BASE at the syscall boundary, so
arch_prctl(ARCH_SET_FS) is safe from userspace. __get_tp() is redirected
through a global uintptr_t (__schos_tp) set at the START of __init_tp(),
before __set_thread_area() is called. The rest of __init_tp() runs
normally so td->locale and the other pthread fields still initialise.
2. src/malloc/mallocng/glue.h - build fix, NOT optional.
mallocng #defines mmap/madvise/mremap to the __-prefixed internals but
does not declare them in this configuration; without these prototypes the
freestanding build gets implicit declarations and the wrong ABI. This had
been applied by hand to the build tree and was MISSING from this patch
file, so any 'make distclean' would have silently lost it.
3. src/malloc/mallocng/meta.h, malloc.c - diagnostics, inert by default.
get_meta()/alloc_group() tracing that dumps group/meta pointers to fd 2,
entirely inside #ifdef SCHOS_MALLOC_DEBUG, which nothing defines. Kept
because this is the instrumentation that resolved the boot-crash
investigation in docs/architecture/kernel-history.md section 1; build
with -DSCHOS_MALLOC_DEBUG to re-enable.
--- a/arch/x86_64/pthread_arch.h 2024-03-01 03:07:33.000000000 +0100
+++ b/arch/x86_64/pthread_arch.h 2026-08-01 19:11:51.533102649 +0200
@@ -1,8 +1,13 @@
+#ifdef __SCHOS__
+extern uintptr_t __schos_tp;
+static inline uintptr_t __get_tp() { return __schos_tp; }
+#else
static inline uintptr_t __get_tp()
{
uintptr_t tp;
__asm__ ("mov %%fs:0,%0" : "=r" (tp) );
return tp;
}
+#endif
#define MC_PC gregs[REG_RIP]
--- a/src/env/__init_tls.c 2024-03-01 03:07:33.000000000 +0100
+++ b/src/env/__init_tls.c 2026-08-01 19:11:54.666345585 +0200
@@ -11,10 +11,19 @@
volatile int __thread_list_lock;
+#ifdef __SCHOS__
+uintptr_t __schos_tp;
+#endif
+
int __init_tp(void *p)
{
pthread_t td = p;
td->self = td;
+ // Set __schos_tp for __get_tp() before calling __set_thread_area.
+ // The kernel now correctly saves/restores FS_BASE at the syscall boundary.
+#ifdef __SCHOS__
+ __schos_tp = (uintptr_t)TP_ADJ(p);
+#endif
int r = __set_thread_area(TP_ADJ(p));
if (r < 0) return -1;
if (!r) libc.can_do_threads = 1;
--- a/src/malloc/mallocng/glue.h 2024-03-01 03:07:33.000000000 +0100
+++ b/src/malloc/mallocng/glue.h 2026-08-01 19:11:57.018230131 +0200
@@ -35,6 +35,10 @@
#define brk(p) ((uintptr_t)__syscall(SYS_brk, p))
+void *__mmap(void *, size_t, int, int, int, off_t);
+int __madvise(void *, size_t, int);
+void *__mremap(void *, size_t, size_t, int, ...);
+
#define mmap __mmap
#define madvise __madvise
#define mremap __mremap
--- a/src/malloc/mallocng/meta.h 2024-03-01 03:07:33.000000000 +0100
+++ b/src/malloc/mallocng/meta.h 2026-08-01 19:11:57.041611644 +0200
@@ -6,6 +6,24 @@
#include <limits.h>
#include "glue.h"
+#ifdef SCHOS_MALLOC_DEBUG
+static void schos_hex(char *out, uint64_t v) {
+ static const char digits[] = "0123456789abcdef";
+ for (int i = 15; i >= 0; i--) { out[i] = digits[v & 0xf]; v >>= 4; }
+}
+static void schos_dbg(const char *tag, uint64_t a, uint64_t b, uint64_t c) {
+ char buf[128];
+ int n = 0;
+ buf[n++]='['; buf[n++]='D'; buf[n++]='B'; buf[n++]='G'; buf[n++]=']'; buf[n++]=' ';
+ for (const char *p = tag; *p; p++) buf[n++] = *p;
+ buf[n++]=' ';
+ schos_hex(buf+n, a); n += 16; buf[n++]=' ';
+ schos_hex(buf+n, b); n += 16; buf[n++]=' ';
+ schos_hex(buf+n, c); n += 16; buf[n++]='\n';
+ __syscall(SYS_write, 2, buf, n);
+}
+#endif
+
__attribute__((__visibility__("hidden")))
extern const uint16_t size_classes[];
@@ -138,6 +156,14 @@
}
const struct group *base = (const void *)(p - UNIT*offset - UNIT);
const struct meta *meta = base->meta;
+#ifdef SCHOS_MALLOC_DEBUG
+ schos_dbg("get_meta p", (uint64_t)p, (uint64_t)offset, (uint64_t)index);
+ {
+ volatile uint64_t *rawbase = (volatile uint64_t *)base;
+ schos_dbg("get_meta RAW reread base[0..2]", rawbase[0], rawbase[1], rawbase[2]);
+ }
+ schos_dbg("get_meta base/meta/meta->mem", (uint64_t)base, (uint64_t)meta, (uint64_t)meta->mem);
+#endif
assert(meta->mem == base);
assert(index <= meta->last_idx);
assert(!(meta->avail_mask & (1u<<index)));
--- a/src/malloc/mallocng/malloc.c 2024-03-01 03:07:33.000000000 +0100
+++ b/src/malloc/mallocng/malloc.c 2026-08-01 19:11:57.026224498 +0200
@@ -280,6 +280,10 @@
m->last_idx = cnt-1;
m->freeable = 1;
m->sizeclass = sc;
+#ifdef SCHOS_MALLOC_DEBUG
+ schos_dbg("alloc_group p/m/cnt", (uint64_t)p, (uint64_t)m, (uint64_t)cnt);
+ schos_dbg("alloc_group readback mem->meta", (uint64_t)m->mem, (uint64_t)m->mem->meta, (uint64_t)sc);
+#endif
return m;
}