Initial commit: Schunix as it stands before the SchOS rename
An x86-64 operating system built from xv6, now largely rewritten: SMP, a copy-on-write root filesystem (SchFS), PCI/USB/virtio drivers, a TTF rasteriser, and a Linux-numbered syscall ABI. No history before this point -- the tree was never under version control. This commit exists so the rename that follows has something to undo to.
This commit is contained in:
commit
d0f7acf9eb
275 changed files with 51417 additions and 0 deletions
54
ports/musl/Makefile
Normal file
54
ports/musl/Makefile
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
# musl libc — MIT-licensed: https://musl.libc.org/
|
||||
#
|
||||
# Installs into $(PREFIX) (= build/ports/musl/prefix), which port.mk exports
|
||||
# to every other port as $(MUSL). Nothing is written into this directory.
|
||||
|
||||
include ../mk/port.mk
|
||||
|
||||
MUSL_VERSION := 1.2.5
|
||||
MUSL_URL := https://musl.libc.org/releases/musl-$(MUSL_VERSION).tar.gz
|
||||
MUSL_SHA256 := a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4
|
||||
|
||||
TARBALL := $(DISTDIR)/musl-$(MUSL_VERSION).tar.gz
|
||||
|
||||
$(TARBALL): | $(DISTDIR)
|
||||
curl -fsSL -o $@ $(MUSL_URL)
|
||||
echo "$(MUSL_SHA256) $@" | sha256sum -c -
|
||||
|
||||
download: $(TARBALL)
|
||||
|
||||
$(SRCDIR): $(TARBALL)
|
||||
mkdir -p $(PORTDIR)
|
||||
tar -xzf $< -C $(PORTDIR)
|
||||
mv $(PORTDIR)/musl-$(MUSL_VERSION) $@
|
||||
|
||||
# $(SRCDIR) is order-only (|) on purpose. The stamp lives INSIDE $(SRCDIR),
|
||||
# so creating it bumps that directory's mtime — making the directory forever
|
||||
# newer than the stamp it contains, and re-running this rule on every single
|
||||
# build. The second run then fails, because the patch does not apply twice.
|
||||
$(SRCDIR)/.patched: patches/0001-schunix-tls.patch | $(SRCDIR)
|
||||
cd $(SRCDIR) && patch -p1 < $(CURDIR)/patches/0001-schunix-tls.patch
|
||||
touch $@
|
||||
|
||||
$(BUILDDIR)/config.mak: $(SRCDIR)/.patched
|
||||
mkdir -p $(BUILDDIR)
|
||||
cd $(BUILDDIR) && $(SRCDIR)/configure \
|
||||
--prefix=$(PREFIX) \
|
||||
--disable-shared \
|
||||
CC=$(CC) \
|
||||
CFLAGS="-D__SCHUNIX__ -fno-stack-protector"
|
||||
|
||||
$(BUILDDIR)/lib/libc.a: $(BUILDDIR)/config.mak
|
||||
$(MAKE) -C $(BUILDDIR)
|
||||
|
||||
$(PREFIX)/lib/libc.a: $(BUILDDIR)/lib/libc.a
|
||||
$(MAKE) -C $(BUILDDIR) install
|
||||
|
||||
install: $(PREFIX)/lib/libc.a
|
||||
|
||||
clean:
|
||||
rm -rf $(PORTDIR)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(TARBALL)
|
||||
133
ports/musl/patches/0001-schunix-tls.patch
Normal file
133
ports/musl/patches/0001-schunix-tls.patch
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
From: Schunix Project <kernel@schunix.org>
|
||||
Subject: [PATCH] schunix: 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 Schunix" and share a lifetime.
|
||||
|
||||
1. arch/x86_64/pthread_arch.h, src/env/__init_tls.c - TLS.
|
||||
Schunix'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 (__schunix_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 SCHUNIX_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 -DSCHUNIX_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 __SCHUNIX__
|
||||
+extern uintptr_t __schunix_tp;
|
||||
+static inline uintptr_t __get_tp() { return __schunix_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 __SCHUNIX__
|
||||
+uintptr_t __schunix_tp;
|
||||
+#endif
|
||||
+
|
||||
int __init_tp(void *p)
|
||||
{
|
||||
pthread_t td = p;
|
||||
td->self = td;
|
||||
+ // Set __schunix_tp for __get_tp() before calling __set_thread_area.
|
||||
+ // The kernel now correctly saves/restores FS_BASE at the syscall boundary.
|
||||
+#ifdef __SCHUNIX__
|
||||
+ __schunix_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 SCHUNIX_MALLOC_DEBUG
|
||||
+static void schunix_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 schunix_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++]=' ';
|
||||
+ schunix_hex(buf+n, a); n += 16; buf[n++]=' ';
|
||||
+ schunix_hex(buf+n, b); n += 16; buf[n++]=' ';
|
||||
+ schunix_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 SCHUNIX_MALLOC_DEBUG
|
||||
+ schunix_dbg("get_meta p", (uint64_t)p, (uint64_t)offset, (uint64_t)index);
|
||||
+ {
|
||||
+ volatile uint64_t *rawbase = (volatile uint64_t *)base;
|
||||
+ schunix_dbg("get_meta RAW reread base[0..2]", rawbase[0], rawbase[1], rawbase[2]);
|
||||
+ }
|
||||
+ schunix_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 SCHUNIX_MALLOC_DEBUG
|
||||
+ schunix_dbg("alloc_group p/m/cnt", (uint64_t)p, (uint64_t)m, (uint64_t)cnt);
|
||||
+ schunix_dbg("alloc_group readback mem->meta", (uint64_t)m->mem, (uint64_t)m->mem->meta, (uint64_t)sc);
|
||||
+#endif
|
||||
return m;
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue