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

113
run.ps1 Normal file
View file

@ -0,0 +1,113 @@
# Schunix launcher (Windows side).
#
# Why this exists: without it you have to hand-type a QEMU command line, and a
# hand-typed one drifts -- notably onto a stale fs.img, which boots to
# "fsinit: invalid file system" because the wrong disk is attached as hdb.
#
# The build no longer goes through WSL. WSL2 runs a real Linux kernel inside a
# Hyper-V VM, so it hard-requires virtualisation, and enabling that puts the
# Hyper-V hypervisor underneath the whole machine -- which makes VMware run
# nested on top of it and slows the box down permanently. Not a trade worth
# making for a build environment.
#
# Instead it builds natively: clang/lld cross-compile the kernel to bare-metal
# ELF, mingw-w64 builds the host tools, and Git Bash supplies make, perl, sed
# and dd. See the Toolchain section of the Makefile.
#
# .\run.ps1 build (native) then boot, windowed
# .\run.ps1 -NoBuild boot whatever is already built
# .\run.ps1 -Headless no window; serial captured to build\serial.log
# .\run.ps1 -Gdb wait for a debugger on :26000 before executing
# .\run.ps1 -SchFS boot the ramdisk-root kernel with a SchFS volume
# attached as hdb; then run cat /proc/schfs
param(
[switch]$NoBuild,
[switch]$Headless,
[switch]$Gdb,
[switch]$SchFS,
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
)
$ErrorActionPreference = 'Stop'
$root = $PSScriptRoot
# The two images QEMU needs. These paths are the single source of truth --
# keep them in sync with the 'qemu' and 'qemu-schfs' targets in the Makefile.
$hda = Join-Path $root 'schunix.img'
$hdb = if ($SchFS) { Join-Path $root 'build\schfs.img' }
else { Join-Path $root 'build\fs.img' }
if (-not $NoBuild) {
Write-Host '==> building (native, no WSL)' -ForegroundColor Cyan
# The three toolchain directories, prepended so the build sees them whether
# or not the current shell happened to inherit them: scoop's shims (make),
# mingw-w64 (host gcc), and LLVM (clang, ld.lld, llvm-objcopy/objdump).
$bash = Join-Path $env:ProgramFiles 'Git\bin\bash.exe'
if (-not (Test-Path $bash)) { throw "Git Bash not found at $bash" }
$toolPath = @(
"$env:USERPROFILE\scoop\shims"
"$env:USERPROFILE\scoop\apps\mingw\current\bin"
"$env:ProgramFiles\LLVM\bin"
) -join ';'
$env:PATH = "$toolPath;$env:PATH"
# -SchFS needs the ramdisk-root kernel: the root filesystem then comes out
# of memory, which leaves device 1 free for the SchFS volume. Booting the
# normal kernel with a SchFS disk as hdb would leave it with no root.
$target = if ($SchFS) { 'make ramroot && make build/schfs.img' } else { 'make' }
& $bash -lc "cd /d/DEV/Schunix && $target"
if ($LASTEXITCODE -ne 0) { throw "build failed (exit $LASTEXITCODE)" }
}
foreach ($img in @($hda, $hdb)) {
if (-not (Test-Path $img)) { throw "missing image: $img (run without -NoBuild)" }
}
# Guard against the exact failure this script exists to prevent: booting against
# a stale or empty hdb. Each format has its own magic in its own place.
$fs = [System.IO.File]::OpenRead($hdb)
try {
$buf = New-Object byte[] 4
# v1: superblock in block 1 with BSIZE 1024, FSMAGIC 0x10203040.
# SchFS: first uberblock in block 1 with SCHFS_BLKSIZE 4096, magic "SchF".
$null = $fs.Seek($(if ($SchFS) { 4096 } else { 1024 }), 'Begin')
$null = $fs.Read($buf, 0, 4)
} finally { $fs.Close() }
if ($SchFS) {
# 0x53636846 little-endian on disk: 46 68 63 53 ("FhcS" byte order).
if ($buf[0] -ne 0x46 -or $buf[1] -ne 0x68 -or $buf[2] -ne 0x63 -or $buf[3] -ne 0x53) {
throw "$hdb is not a valid SchFS image (bad uberblock magic). Rebuild it: make build/schfs.img"
}
} else {
if ($buf[0] -ne 0x40 -or $buf[1] -ne 0x30 -or $buf[2] -ne 0x20 -or $buf[3] -ne 0x10) {
throw "$hdb is not a valid SCHFS image (bad superblock magic). Rebuild it: rm -f build/fs.img && make"
}
}
$qemuArgs = @(
'-drive', "file=$hda,format=raw,index=0,media=disk"
'-drive', "file=$hdb,format=raw,index=1,media=disk"
'-m', '1G'
'-smp', '2'
'-cpu', 'qemu64,+rdtscp'
'-machine', 'pc-i440fx-9.2'
)
if ($Headless) {
$log = Join-Path $root 'build\serial.log'
$qemuArgs += @('-display', 'none', '-serial', "file:$log")
Write-Host "==> headless; serial -> $log" -ForegroundColor Cyan
} else {
$qemuArgs += @('-vga', 'std', '-serial', 'stdio')
}
if ($Gdb) {
$qemuArgs += @('-gdb', 'tcp::26000', '-S')
Write-Host '==> paused for gdb on localhost:26000' -ForegroundColor Yellow
}
& $Qemu @qemuArgs