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:
Nexoniarz 2026-08-09 13:47:01 +02:00
commit d0f7acf9eb
275 changed files with 51417 additions and 0 deletions

View file

@ -0,0 +1,93 @@
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View file

@ -0,0 +1,79 @@
JetBrains Mono Variable Font
============================
This download contains JetBrains Mono as both variable fonts and static fonts.
JetBrains Mono is a variable font with this axis:
wght
This means all the styles are contained in these files:
JetBrainsMono-VariableFont_wght.ttf
JetBrainsMono-Italic-VariableFont_wght.ttf
If your app fully supports variable fonts, you can now pick intermediate styles
that aren’t available as static fonts. Not all apps support variable fonts, and
in those cases you can use the static font files for JetBrains Mono:
static/JetBrainsMono-Thin.ttf
static/JetBrainsMono-ExtraLight.ttf
static/JetBrainsMono-Light.ttf
static/JetBrainsMono-Regular.ttf
static/JetBrainsMono-Medium.ttf
static/JetBrainsMono-SemiBold.ttf
static/JetBrainsMono-Bold.ttf
static/JetBrainsMono-ExtraBold.ttf
static/JetBrainsMono-ThinItalic.ttf
static/JetBrainsMono-ExtraLightItalic.ttf
static/JetBrainsMono-LightItalic.ttf
static/JetBrainsMono-Italic.ttf
static/JetBrainsMono-MediumItalic.ttf
static/JetBrainsMono-SemiBoldItalic.ttf
static/JetBrainsMono-BoldItalic.ttf
static/JetBrainsMono-ExtraBoldItalic.ttf
Get started
-----------
1. Install the font files you want to use
2. Use your app's font picker to view the font family and all the
available styles
Learn more about variable fonts
-------------------------------
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
https://variablefonts.typenetwork.com
https://medium.com/variable-fonts
In desktop apps
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
Online
https://developers.google.com/fonts/docs/getting_started
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
Installing fonts
MacOS: https://support.apple.com/en-us/HT201749
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
Android Apps
https://developers.google.com/fonts/docs/android
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
License
-------
Please read the full license text (OFL.txt) to understand the permissions,
restrictions and requirements for usage, redistribution, and modification.
You can use them in your products & projects – print or digital,
commercial or otherwise.
This isn't legal advice, please consider consulting a lawyer and see the full
license for all details.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

34
ports/Makefile Normal file
View file

@ -0,0 +1,34 @@
# SPDX-License-Identifier: Apache-2.0
# Schunix ports — third-party software, one directory per port.
# All ports are permissive-licensed (MIT, BSD, 0BSD, Apache 2.0).
#
# ports/musl/ libc — installs headers/libs to build/ports/musl/prefix
# ports/mksh/ MirBSD Korn Shell — installed as sysroot/bin/sh
# ports/toybox/ core utilities — installed as sysroot/bin/<applet>
#
# A port directory holds only a Makefile and optional patches/. Everything
# generated lives in build/ports/<name>/ — see mk/port.mk for the contract.
# Tarballs are cached in dist/ and are never removed by 'clean'.
#
# Order matters: musl must be built before anything that links against it.
# Ports that live in this directory but are deliberately not built by `make`.
# Empty for now; the filter stays because the reason it existed will recur --
# a port whose licence cannot be combined with Apache-2.0 can be kept here for
# local testing but must never be built into a Schunix image.
NOTPORTS :=
PORTS := $(filter-out $(NOTPORTS), \
$(patsubst %/,%,$(sort $(dir $(wildcard */Makefile)))))
.PHONY: all $(PORTS) clean distclean
all: $(PORTS)
mksh: musl
toybox: musl
$(PORTS):
$(MAKE) -C $@
clean distclean:
for p in $(PORTS); do $(MAKE) -C $$p $@; done

93
ports/Roboto/OFL.txt Normal file
View file

@ -0,0 +1,93 @@
Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

118
ports/Roboto/README.txt Normal file
View file

@ -0,0 +1,118 @@
Roboto Variable Font
====================
This download contains Roboto as both variable fonts and static fonts.
Roboto is a variable font with these axes:
wdth
wght
This means all the styles are contained in these files:
Roboto-VariableFont_wdth,wght.ttf
Roboto-Italic-VariableFont_wdth,wght.ttf
If your app fully supports variable fonts, you can now pick intermediate styles
that aren’t available as static fonts. Not all apps support variable fonts, and
in those cases you can use the static font files for Roboto:
static/Roboto_Condensed-Thin.ttf
static/Roboto_Condensed-ExtraLight.ttf
static/Roboto_Condensed-Light.ttf
static/Roboto_Condensed-Regular.ttf
static/Roboto_Condensed-Medium.ttf
static/Roboto_Condensed-SemiBold.ttf
static/Roboto_Condensed-Bold.ttf
static/Roboto_Condensed-ExtraBold.ttf
static/Roboto_Condensed-Black.ttf
static/Roboto_SemiCondensed-Thin.ttf
static/Roboto_SemiCondensed-ExtraLight.ttf
static/Roboto_SemiCondensed-Light.ttf
static/Roboto_SemiCondensed-Regular.ttf
static/Roboto_SemiCondensed-Medium.ttf
static/Roboto_SemiCondensed-SemiBold.ttf
static/Roboto_SemiCondensed-Bold.ttf
static/Roboto_SemiCondensed-ExtraBold.ttf
static/Roboto_SemiCondensed-Black.ttf
static/Roboto-Thin.ttf
static/Roboto-ExtraLight.ttf
static/Roboto-Light.ttf
static/Roboto-Regular.ttf
static/Roboto-Medium.ttf
static/Roboto-SemiBold.ttf
static/Roboto-Bold.ttf
static/Roboto-ExtraBold.ttf
static/Roboto-Black.ttf
static/Roboto_Condensed-ThinItalic.ttf
static/Roboto_Condensed-ExtraLightItalic.ttf
static/Roboto_Condensed-LightItalic.ttf
static/Roboto_Condensed-Italic.ttf
static/Roboto_Condensed-MediumItalic.ttf
static/Roboto_Condensed-SemiBoldItalic.ttf
static/Roboto_Condensed-BoldItalic.ttf
static/Roboto_Condensed-ExtraBoldItalic.ttf
static/Roboto_Condensed-BlackItalic.ttf
static/Roboto_SemiCondensed-ThinItalic.ttf
static/Roboto_SemiCondensed-ExtraLightItalic.ttf
static/Roboto_SemiCondensed-LightItalic.ttf
static/Roboto_SemiCondensed-Italic.ttf
static/Roboto_SemiCondensed-MediumItalic.ttf
static/Roboto_SemiCondensed-SemiBoldItalic.ttf
static/Roboto_SemiCondensed-BoldItalic.ttf
static/Roboto_SemiCondensed-ExtraBoldItalic.ttf
static/Roboto_SemiCondensed-BlackItalic.ttf
static/Roboto-ThinItalic.ttf
static/Roboto-ExtraLightItalic.ttf
static/Roboto-LightItalic.ttf
static/Roboto-Italic.ttf
static/Roboto-MediumItalic.ttf
static/Roboto-SemiBoldItalic.ttf
static/Roboto-BoldItalic.ttf
static/Roboto-ExtraBoldItalic.ttf
static/Roboto-BlackItalic.ttf
Get started
-----------
1. Install the font files you want to use
2. Use your app's font picker to view the font family and all the
available styles
Learn more about variable fonts
-------------------------------
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
https://variablefonts.typenetwork.com
https://medium.com/variable-fonts
In desktop apps
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
Online
https://developers.google.com/fonts/docs/getting_started
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
Installing fonts
MacOS: https://support.apple.com/en-us/HT201749
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
Android Apps
https://developers.google.com/fonts/docs/android
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
License
-------
Please read the full license text (OFL.txt) to understand the permissions,
restrictions and requirements for usage, redistribution, and modification.
You can use them in your products & projects – print or digital,
commercial or otherwise.
This isn't legal advice, please consider consulting a lawyer and see the full
license for all details.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

48
ports/mk/port.mk Normal file
View file

@ -0,0 +1,48 @@
# SPDX-License-Identifier: Apache-2.0
# Shared definitions for all Schunix ports.
# Include this at the top of each port's Makefile: include ../mk/port.mk
#
# Layout contract — a port directory contains ONLY hand-written files:
#
# ports/<name>/Makefile required
# ports/<name>/patches/* optional
#
# Everything generated goes under $(PORTDIR) = build/ports/<name>/ :
#
# build/ports/<name>/src extracted upstream tarball
# build/ports/<name>/obj out-of-tree build directory
# build/ports/<name>/prefix install prefix (musl's headers/libs land here)
#
# If a file appears inside ports/<name>/ that you did not write by hand,
# it is in the wrong place. `make clean` deletes $(PORTDIR) and nothing else.
PORTSDIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/..)
TOPDIR := $(abspath $(PORTSDIR)/..)
SYSROOT := $(TOPDIR)/sysroot
DISTDIR := $(TOPDIR)/dist
BUILDROOT := $(TOPDIR)/build/ports
# Port name is the directory name — no per-port boilerplate needed.
PORT := $(notdir $(CURDIR))
PORTDIR := $(BUILDROOT)/$(PORT)
SRCDIR := $(PORTDIR)/src
BUILDDIR := $(PORTDIR)/obj
PREFIX := $(PORTDIR)/prefix
# musl is the libc every other port links against; its install prefix is a
# fixed location so ports don't need to know where musl's own source lives.
MUSL := $(BUILDROOT)/musl/prefix
CC := clang
# FS register belongs to the kernel; never let the compiler touch %fs directly.
CFLAGS_BT := -fno-stack-protector
.PHONY: all download extract build install clean distclean
all: install
$(DISTDIR):
mkdir -p $(DISTDIR)
$(SYSROOT)/bin:
mkdir -p $@

45
ports/mksh/Makefile Normal file
View file

@ -0,0 +1,45 @@
# SPDX-License-Identifier: Apache-2.0
# mksh (MirBSD Korn Shell) — permissive: https://www.mirbsd.org/mksh.htm
# Installed as /bin/sh — Schunix standardizes on "sh" as the one shell name;
# no ksh/dash/other aliases are installed or looked up by init.
include ../mk/port.mk
MKSH_VERSION := R59c
MKSH_URL := http://www.mirbsd.org/MirOS/dist/mir/mksh/mksh-$(MKSH_VERSION).tgz
TARBALL := $(DISTDIR)/mksh-$(MKSH_VERSION).tgz
CFLAGS := -static -D__SCHUNIX__ -I$(MUSL)/include -fno-stack-protector
LDFLAGS := -static -L$(MUSL)/lib -lc
$(TARBALL): | $(DISTDIR)
curl -fsSL --tlsv1.0 -o $@ $(MKSH_URL)
download: $(TARBALL)
$(SRCDIR): $(TARBALL)
mkdir -p $(PORTDIR)
tar -xzf $< -C $(PORTDIR)
mv $(PORTDIR)/mksh $@
# Order-only (|) on $(SRCDIR): the extracted tarball never changes, so a
# directory mtime should not trigger a rebuild of an already-built shell.
$(BUILDDIR)/lksh: | $(SRCDIR)
mkdir -p $(BUILDDIR)
cd $(BUILDDIR) && \
CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
sh $(SRCDIR)/Build.sh -r -L
$(SYSROOT)/bin/sh: $(BUILDDIR)/lksh | $(SYSROOT)/bin
cp $< $@
chmod 755 $@
install: $(SYSROOT)/bin/sh
clean:
rm -rf $(PORTDIR)
distclean: clean
rm -f $(TARBALL)

54
ports/musl/Makefile Normal file
View 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)

View 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;
}

82
ports/toybox/Makefile Normal file
View file

@ -0,0 +1,82 @@
# SPDX-License-Identifier: Apache-2.0
# toybox — 0BSD-licensed: https://landley.net/toybox/
# Provides Schunix's core utilities (ls, cat, cp, mv, rm, mkdir, ...) as a
# single multicall binary, installed under sysroot/bin/ once per applet name.
#
# mkfs (tools/mkfs.c) doesn't understand symlinks or hardlink dedup — each
# sysroot/bin/<name> below is a real, independent copy of the same toybox
# binary. That costs disk space per applet instead of one shared inode, but
# needs no changes to mkfs and keeps this Makefile self-contained.
include ../mk/port.mk
TOYBOX_VERSION := 0.8.12
TOYBOX_URL := http://landley.net/toybox/downloads/toybox-$(TOYBOX_VERSION).tar.gz
TOYBOX_SHA256 := ad88a921133ae2231d9f2df875ec0bd42af4429145caea7d7db9e02208a6fd2e
TARBALL := $(DISTDIR)/toybox-$(TOYBOX_VERSION).tar.gz
CFLAGS := -static -D__SCHUNIX__ -I$(MUSL)/include -fno-stack-protector
LDFLAGS := -static -L$(MUSL)/lib -lc
# The applet list is not hard-coded any more: `toybox` with no arguments prints
# exactly the applets the binary was built with, so the install below asks the
# binary itself. A hand-maintained list installed 57 of the ~250 available and
# silently drifted every time the toybox config changed.
$(TARBALL): | $(DISTDIR)
curl -fsSL -o $@ $(TOYBOX_URL)
echo "$(TOYBOX_SHA256) $@" | sha256sum -c -
download: $(TARBALL)
$(SRCDIR): $(TARBALL)
mkdir -p $(PORTDIR)
tar -xzf $< -C $(PORTDIR)
mv $(PORTDIR)/toybox-$(TOYBOX_VERSION) $@
# toybox has no out-of-tree build mode, so its source is copied into $(BUILDDIR)
# and built in place. $(SRCDIR) is an order-only prerequisite (|): the extracted
# tarball never changes, and depending on it normally made a directory mtime
# trigger a rebuild. The rebuild then failed anyway, because `cp -r` over a
# populated $(BUILDDIR) hits "File exists" on kconfig's symlinks — so wipe it
# first and always build from a clean copy.
$(BUILDDIR)/toybox: | $(SRCDIR)
rm -rf $(BUILDDIR)
mkdir -p $(BUILDDIR)
cp -r $(SRCDIR)/. $(BUILDDIR)/
$(MAKE) -C $(BUILDDIR) defconfig
$(MAKE) -C $(BUILDDIR) CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"
# Install every applet the binary provides, one name per applet.
#
# mkfs deduplicates by content, so all of these collapse to a single inode with
# many hard links in the image -- the cost is one copy, not one per name. On the
# host we try a hard link first for the same reason and fall back to a copy if
# the filesystem will not take one (NTFS via WSL usually will).
#
# The work hangs off a stamp file rather than off the phony `install` target.
# port.mk declares install .PHONY for every port, so this recipe used to run on
# every single build -- re-creating 236 links whether or not toybox had been
# rebuilt. That is slow on its own, and worse, it bumped the mtime of 236 files
# in sysroot/ every time, which made the top-level build think the staged tree
# had changed and rebuild the whole filesystem image from scratch.
install: $(BUILDDIR)/toybox.installed
$(BUILDDIR)/toybox.installed: $(BUILDDIR)/toybox | $(SYSROOT)/bin
cp $< $(SYSROOT)/bin/toybox
chmod 755 $(SYSROOT)/bin/toybox
@for a in $$($(BUILDDIR)/toybox); do \
rm -f $(SYSROOT)/bin/"$$a"; \
ln $(SYSROOT)/bin/toybox $(SYSROOT)/bin/"$$a" 2>/dev/null \
|| cp $< $(SYSROOT)/bin/"$$a"; \
done
@echo "toybox: installed $$($(BUILDDIR)/toybox | wc -w) applets"
@touch $@
clean:
rm -rf $(PORTDIR)
distclean: clean
rm -f $(TARBALL)