Build and tools work on Linux, macOS and BSD as well as Windows

Developed from both Windows and Linux, so nothing in the build should
care which host it runs on. It did, in four places.

Toolchain: one path instead of two. clang is a cross-compiler by
construction, so a single LLVM install targets bare-metal ELF, 16/32-bit
code below 1 MB, and Linux/musl userland from any host -- which is how
the Windows build already worked. The GNU branch beside it had drifted
into passing --no-warn-rwx-segments, a hard error on lld, which is the
default linker on both FreeBSD and macOS; and it required a brewed
x86_64-elf-gcc before anything built on a Mac at all. GNU is kept as a
fallback (USE_GNU=1) but clang+lld is chosen whenever both are present.
Host tools use the host's own cc; only mingw needs naming explicitly.

tools/mkschfs.c included <sys/sysmacros.h> unconditionally on non-mingw
hosts. That header is glibc/musl only -- macOS and the BSDs have neither
the header nor a need for it, since major()/minor() come from
<sys/types.h> there. Now guarded on __linux__.

Ports verified tarballs with `sha256sum -c -`, which does not exist on
macOS (shasum), FreeBSD/NetBSD (sha256), or OpenBSD (cksum -a sha256),
and each spells its check mode differently. tools/sha256check.sh picks
whichever of the five the host has and compares digests itself.

nproc is coreutils, so absent on macOS and BSD; falls through to sysctl
-n hw.ncpu before defaulting to 4.

The PowerShell tools now run under pwsh on any OS: QEMU is found on PATH
(the scoop location is a Windows-only fallback), and path literals use
forward slashes -- Join-Path $root 'build\x' produces a *filename
containing a backslash* on a Unix host. The backslash sweep is limited
to known directory prefixes on purpose: bootcheck sends
printf 'caf\303\251' to the guest to test UTF-8, and a blanket
substitution would have quietly changed what that asserts.

Also fixes six tools left booting build/fs.img, which stopped being
bootable when SchFS became the root filesystem: crashshot, dispshot,
fbshot, splashshot, textshot and ttyshot all take build/schfs.img now,
and the -SchFS switches that used to select it are gone.

Verified on Windows: full build, and bootcheck green. The Linux, macOS
and BSD paths are written from their documented behaviour and are NOT
executed here -- this machine has no WSL and no second host.
This commit is contained in:
Nexoniarz 2026-08-09 14:24:53 +02:00
commit cda5908660
15 changed files with 427 additions and 105 deletions

View file

@ -17,8 +17,8 @@
# the pacing below -- not superstition, just the difference between a reliable
# check and a flaky one.
#
# tools\bootcheck.ps1
# tools\bootcheck.ps1 -Tty -Ps
# tools/bootcheck.ps1
# tools/bootcheck.ps1 -Tty -Ps
param(
[switch]$Fb,
@ -49,16 +49,39 @@ param(
# else in this suite touches.
[switch]$Ps,
[int]$BootSeconds = 20,
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
[string]$Qemu = (Find-Qemu)
)
# QEMU, on whichever host this is.
#
# PowerShell 7 runs on Linux, macOS and the BSDs as well as Windows, so these
# scripts are usable from all of them -- but the old default was a hardcoded
# scoop path under $env:USERPROFILE, which exists on exactly one of those. PATH
# first, because a package-managed qemu is on it everywhere; the scoop location
# is only a fallback for the Windows install that does not add itself to PATH.
function Find-Qemu {
$exe = if ($IsWindows -or $env:OS -eq 'Windows_NT') { 'qemu-system-x86_64.exe' }
else { 'qemu-system-x86_64' }
$onPath = Get-Command $exe -ErrorAction SilentlyContinue
if ($onPath) { return $onPath.Source }
if ($env:USERPROFILE) {
$scoop = Join-Path (Join-Path $env:USERPROFILE 'scoop/apps/qemu/current') $exe
if (Test-Path $scoop) { return $scoop }
}
foreach ($p in @('/usr/bin', '/usr/local/bin', '/opt/homebrew/bin')) {
$c = Join-Path $p $exe
if (Test-Path $c) { return $c }
}
throw "qemu-system-x86_64 not found on PATH. Install QEMU, or pass -Qemu <path>."
}
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$hda = Join-Path $root 'schos.img'
# The root filesystem. SchFS is the only root there is, so this is not a
# choice -- a kernel handed anything else on device 1 panics in forkret().
$hdb = Join-Path $root 'build\schfs.img'
$log = Join-Path $root 'build\bootcheck.log'
$hdb = Join-Path $root 'build/schfs.img'
$log = Join-Path $root 'build/bootcheck.log'
Remove-Item -Force $log -ErrorAction SilentlyContinue
@ -196,7 +219,7 @@ $usbDevices = if ($Usb) {
# there, which failed three USB checks that had nothing wrong with USB.
# It also stops the same file being attached twice, once as the root
# disk and once as a USB device.
"-drive id=usbstick,file=`"$(Join-Path $root 'build\fs.img')`",format=raw,if=none"
"-drive id=usbstick,file=`"$(Join-Path $root 'build/fs.img')`",format=raw,if=none"
'-device usb-storage,bus=xhci.0,drive=usbstick')
} else { @() }

View file

@ -9,23 +9,48 @@
# shell. screendump writes a PPM; the PNG conversion is optional and skipped if
# ImageMagick is not around.
#
# tools\crashshot.ps1 crash the ramdisk-root build
# tools\crashshot.ps1 -SchFS with a SchFS volume attached
# tools/crashshot.ps1 crash the ramdisk-root build
param(
[switch]$SchFS,
[int]$BootSeconds = 20,
[string]$Out = "build\crashscreen.ppm",
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
[string]$Out = "build/crashscreen.ppm",
[string]$Qemu = (Find-Qemu)
)
# QEMU, on whichever host this is.
#
# PowerShell 7 runs on Linux, macOS and the BSDs as well as Windows, so these
# scripts are usable from all of them -- but the old default was a hardcoded
# scoop path under $env:USERPROFILE, which exists on exactly one of those. PATH
# first, because a package-managed qemu is on it everywhere; the scoop location
# is only a fallback for the Windows install that does not add itself to PATH.
function Find-Qemu {
$exe = if ($IsWindows -or $env:OS -eq 'Windows_NT') { 'qemu-system-x86_64.exe' }
else { 'qemu-system-x86_64' }
$onPath = Get-Command $exe -ErrorAction SilentlyContinue
if ($onPath) { return $onPath.Source }
if ($env:USERPROFILE) {
$scoop = Join-Path (Join-Path $env:USERPROFILE 'scoop/apps/qemu/current') $exe
if (Test-Path $scoop) { return $scoop }
}
foreach ($p in @('/usr/bin', '/usr/local/bin', '/opt/homebrew/bin')) {
$c = Join-Path $p $exe
if (Test-Path $c) { return $c }
}
throw "qemu-system-x86_64 not found on PATH. Install QEMU, or pass -Qemu <path>."
}
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$hda = Join-Path $root 'schos.img'
$hdb = if ($SchFS) { Join-Path $root 'build\schfs.img' } else { Join-Path $root 'build\fs.img' }
$log = Join-Path $root 'build\crashshot.log'
# The root filesystem. SchFS is the only root there is: the kernel mounts
# device 1 in forkret() and panics if it is not a SchFS volume, so this is
# not a choice and there is no -SchFS switch any more. It used to default to
# build/fs.img, which stopped being bootable the moment SchFS became root.
$hdb = Join-Path $root 'build/schfs.img'
$log = Join-Path $root 'build/crashshot.log'
$ppm = Join-Path $root $Out
$mon = Join-Path $root 'build\qemu-mon.sock'
$mon = Join-Path $root 'build/qemu-mon.sock'
Remove-Item -Force $log, $ppm -ErrorAction SilentlyContinue

View file

@ -14,23 +14,48 @@
# shell. screendump writes a PPM; the PNG conversion is optional and skipped if
# ImageMagick is not around.
#
# tools\crashshot.ps1 crash the ramdisk-root build
# tools\crashshot.ps1 -SchFS with a SchFS volume attached
# tools/crashshot.ps1 crash the ramdisk-root build
param(
[switch]$SchFS,
[int]$BootSeconds = 20,
[string]$Out = "build\dispshot.ppm",
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
[string]$Out = "build/dispshot.ppm",
[string]$Qemu = (Find-Qemu)
)
# QEMU, on whichever host this is.
#
# PowerShell 7 runs on Linux, macOS and the BSDs as well as Windows, so these
# scripts are usable from all of them -- but the old default was a hardcoded
# scoop path under $env:USERPROFILE, which exists on exactly one of those. PATH
# first, because a package-managed qemu is on it everywhere; the scoop location
# is only a fallback for the Windows install that does not add itself to PATH.
function Find-Qemu {
$exe = if ($IsWindows -or $env:OS -eq 'Windows_NT') { 'qemu-system-x86_64.exe' }
else { 'qemu-system-x86_64' }
$onPath = Get-Command $exe -ErrorAction SilentlyContinue
if ($onPath) { return $onPath.Source }
if ($env:USERPROFILE) {
$scoop = Join-Path (Join-Path $env:USERPROFILE 'scoop/apps/qemu/current') $exe
if (Test-Path $scoop) { return $scoop }
}
foreach ($p in @('/usr/bin', '/usr/local/bin', '/opt/homebrew/bin')) {
$c = Join-Path $p $exe
if (Test-Path $c) { return $c }
}
throw "qemu-system-x86_64 not found on PATH. Install QEMU, or pass -Qemu <path>."
}
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$hda = Join-Path $root 'schos.img'
$hdb = if ($SchFS) { Join-Path $root 'build\schfs.img' } else { Join-Path $root 'build\fs.img' }
$log = Join-Path $root 'build\crashshot.log'
# The root filesystem. SchFS is the only root there is: the kernel mounts
# device 1 in forkret() and panics if it is not a SchFS volume, so this is
# not a choice and there is no -SchFS switch any more. It used to default to
# build/fs.img, which stopped being bootable the moment SchFS became root.
$hdb = Join-Path $root 'build/schfs.img'
$log = Join-Path $root 'build/crashshot.log'
$ppm = Join-Path $root $Out
$mon = Join-Path $root 'build\qemu-mon.sock'
$mon = Join-Path $root 'build/qemu-mon.sock'
Remove-Item -Force $log, $ppm -ErrorAction SilentlyContinue

View file

@ -6,22 +6,49 @@
# every byte accepted, and the only symptom is a picture that shears
# progressively down the screen. That is a thing you have to look at.
#
# tools\fbshot.ps1 gradient through mmap
# tools\fbshot.ps1 -Mode bars colour bars through write()
# tools/fbshot.ps1 gradient through mmap
# tools/fbshot.ps1 -Mode bars colour bars through write()
param(
[ValidateSet('fill', 'bars')]
[string]$Mode = 'fill',
[int]$BootSeconds = 20,
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
[string]$Qemu = (Find-Qemu)
)
# QEMU, on whichever host this is.
#
# PowerShell 7 runs on Linux, macOS and the BSDs as well as Windows, so these
# scripts are usable from all of them -- but the old default was a hardcoded
# scoop path under $env:USERPROFILE, which exists on exactly one of those. PATH
# first, because a package-managed qemu is on it everywhere; the scoop location
# is only a fallback for the Windows install that does not add itself to PATH.
function Find-Qemu {
$exe = if ($IsWindows -or $env:OS -eq 'Windows_NT') { 'qemu-system-x86_64.exe' }
else { 'qemu-system-x86_64' }
$onPath = Get-Command $exe -ErrorAction SilentlyContinue
if ($onPath) { return $onPath.Source }
if ($env:USERPROFILE) {
$scoop = Join-Path (Join-Path $env:USERPROFILE 'scoop/apps/qemu/current') $exe
if (Test-Path $scoop) { return $scoop }
}
foreach ($p in @('/usr/bin', '/usr/local/bin', '/opt/homebrew/bin')) {
$c = Join-Path $p $exe
if (Test-Path $c) { return $c }
}
throw "qemu-system-x86_64 not found on PATH. Install QEMU, or pass -Qemu <path>."
}
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$hda = Join-Path $root 'schos.img'
$hdb = Join-Path $root 'build\fs.img'
$log = Join-Path $root 'build\fbshot.log'
$ppm = Join-Path $root "build\fb-$Mode.ppm"
# The root filesystem. SchFS is the only root there is: the kernel mounts
# device 1 in forkret() and panics if it is not a SchFS volume, so this is
# not a choice and there is no -SchFS switch any more. It used to default to
# build/fs.img, which stopped being bootable the moment SchFS became root.
$hdb = Join-Path $root 'build/schfs.img'
$log = Join-Path $root 'build/fbshot.log'
$ppm = Join-Path $root "build/fb-$Mode.ppm"
Remove-Item -Force $log, $ppm -ErrorAction SilentlyContinue

View file

@ -6,9 +6,9 @@
# counts only first-party code, and separates the code from the comments so the
# number means something.
#
# tools\loc.ps1 the summary table
# tools\loc.ps1 -PerFile every file, largest first
# tools\loc.ps1 -All include third-party trees, for comparison
# tools/loc.ps1 the summary table
# tools/loc.ps1 -PerFile every file, largest first
# tools/loc.ps1 -All include third-party trees, for comparison
#
# Comment detection is deliberately simple: it handles // and /* */ for C and
# # for scripts, and does not try to understand a // inside a string literal.

View file

@ -4,9 +4,9 @@
# El Torito image. The ramdisk root is the point: the ISO carries a complete
# userland inside the kernel, so it boots with no hard disk attached at all.
#
# tools\makeiso.ps1 build it
# tools\makeiso.ps1 -Run build it, then boot it under QEMU to check
# tools\makeiso.ps1 -Clean force a full rebuild first
# tools/makeiso.ps1 build it
# tools/makeiso.ps1 -Run build it, then boot it under QEMU to check
# tools/makeiso.ps1 -Clean force a full rebuild first
#
# Afterwards the ISO is schos.iso in the repository root; point a VM's optical
# drive at it and boot from CD.
@ -14,9 +14,32 @@
param(
[switch]$Run,
[switch]$Clean,
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
[string]$Qemu = (Find-Qemu)
)
# QEMU, on whichever host this is.
#
# PowerShell 7 runs on Linux, macOS and the BSDs as well as Windows, so these
# scripts are usable from all of them -- but the old default was a hardcoded
# scoop path under $env:USERPROFILE, which exists on exactly one of those. PATH
# first, because a package-managed qemu is on it everywhere; the scoop location
# is only a fallback for the Windows install that does not add itself to PATH.
function Find-Qemu {
$exe = if ($IsWindows -or $env:OS -eq 'Windows_NT') { 'qemu-system-x86_64.exe' }
else { 'qemu-system-x86_64' }
$onPath = Get-Command $exe -ErrorAction SilentlyContinue
if ($onPath) { return $onPath.Source }
if ($env:USERPROFILE) {
$scoop = Join-Path (Join-Path $env:USERPROFILE 'scoop/apps/qemu/current') $exe
if (Test-Path $scoop) { return $scoop }
}
foreach ($p in @('/usr/bin', '/usr/local/bin', '/opt/homebrew/bin')) {
$c = Join-Path $p $exe
if (Test-Path $c) { return $c }
}
throw "qemu-system-x86_64 not found on PATH. Install QEMU, or pass -Qemu <path>."
}
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
Push-Location $root
@ -117,7 +140,7 @@ Write-Host " RAM: 64 MB is plenty. The old 224 MB floor is gone."
if ($Run) {
Write-Host ""
Write-Host "==> booting the ISO under QEMU, no disk attached" -ForegroundColor Cyan
$log = Join-Path $root 'build\isoboot.log'
$log = Join-Path $root 'build/isoboot.log'
if (Test-Path $log) { Clear-Content $log }
$psi = New-Object System.Diagnostics.ProcessStartInfo

View file

@ -55,7 +55,12 @@
#define S_ISLNK(m) 0
static long readlink(const char *p, char *b, unsigned long n)
{ (void)p; (void)b; (void)n; return -1; }
#else
#elif defined(__linux__)
/* glibc and musl both put major()/minor() here, and glibc warns and then
errors if you take them from <sys/types.h> instead. Linux only: macOS and
the BSDs have no <sys/sysmacros.h> at all and define both in <sys/types.h>,
which is already included above -- including it unconditionally is a build
failure on every non-Linux Unix. */
#include <sys/sysmacros.h>
#endif

62
tools/sha256check.sh Normal file
View file

@ -0,0 +1,62 @@
#!/bin/sh
# Verify a file's SHA-256 against an expected hex digest, on any host.
#
# tools/sha256check.sh <expected-hex> <file>
#
# There is no one checksum command across the supported hosts. Linux and Git
# Bash have coreutils' sha256sum; macOS ships shasum(1) and no sha256sum;
# FreeBSD and NetBSD ship sha256(1) with a different output format again;
# OpenBSD has sha256 too but usually reached through cksum -a sha256. A recipe
# that hardcodes any one of them builds on some of the hosts this project
# supports and fails on the rest, and the failure arrives only when someone
# first runs `make ports` on a Mac.
#
# Compares digests rather than trusting a -c flag, because the -c input format
# differs between the implementations as well.
set -eu
if [ $# -ne 2 ]; then
echo "usage: $0 <expected-sha256> <file>" >&2
exit 2
fi
expected="$1"
file="$2"
if [ ! -f "$file" ]; then
echo "sha256check: no such file: $file" >&2
exit 1
fi
actual=
if command -v sha256sum >/dev/null 2>&1; then
actual=$(sha256sum "$file" | cut -d' ' -f1)
elif command -v shasum >/dev/null 2>&1; then
actual=$(shasum -a 256 "$file" | cut -d' ' -f1)
elif command -v sha256 >/dev/null 2>&1; then
# FreeBSD/NetBSD: -q prints the digest alone.
actual=$(sha256 -q "$file")
elif command -v cksum >/dev/null 2>&1 && cksum -a sha256 /dev/null >/dev/null 2>&1; then
# OpenBSD.
actual=$(cksum -a sha256 "$file" | sed 's/.*= *//')
elif command -v openssl >/dev/null 2>&1; then
actual=$(openssl dgst -sha256 "$file" | sed 's/.*= *//')
else
echo "sha256check: no usable checksum tool found" >&2
echo " looked for: sha256sum, shasum, sha256, cksum, openssl" >&2
exit 1
fi
# Case-insensitive: openssl and sha256 have been known to differ here.
expected_lc=$(printf '%s' "$expected" | tr 'A-Z' 'a-z')
actual_lc=$(printf '%s' "$actual" | tr 'A-Z' 'a-z')
if [ "$expected_lc" != "$actual_lc" ]; then
echo "sha256check: checksum mismatch for $file" >&2
echo " expected: $expected_lc" >&2
echo " actual: $actual_lc" >&2
exit 1
fi
echo "$file: OK"

View file

@ -10,19 +10,42 @@
# Same shape as tools/crashshot.ps1: monitor on TCP because QEMU on Windows has
# no unix sockets, serial to a logfile so the transcript survives.
#
# tools\splashshot.ps1 frames every 400ms for 8s
# tools\splashshot.ps1 -Every 200 -For 4
# tools/splashshot.ps1 frames every 400ms for 8s
# tools/splashshot.ps1 -Every 200 -For 4
param(
[int]$Every = 400, # milliseconds between frames
[int]$For = 8, # seconds to keep capturing
[string]$OutDir = "build\shots",
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
[string]$OutDir = "build/shots",
[string]$Qemu = (Find-Qemu)
)
# QEMU, on whichever host this is.
#
# PowerShell 7 runs on Linux, macOS and the BSDs as well as Windows, so these
# scripts are usable from all of them -- but the old default was a hardcoded
# scoop path under $env:USERPROFILE, which exists on exactly one of those. PATH
# first, because a package-managed qemu is on it everywhere; the scoop location
# is only a fallback for the Windows install that does not add itself to PATH.
function Find-Qemu {
$exe = if ($IsWindows -or $env:OS -eq 'Windows_NT') { 'qemu-system-x86_64.exe' }
else { 'qemu-system-x86_64' }
$onPath = Get-Command $exe -ErrorAction SilentlyContinue
if ($onPath) { return $onPath.Source }
if ($env:USERPROFILE) {
$scoop = Join-Path (Join-Path $env:USERPROFILE 'scoop/apps/qemu/current') $exe
if (Test-Path $scoop) { return $scoop }
}
foreach ($p in @('/usr/bin', '/usr/local/bin', '/opt/homebrew/bin')) {
$c = Join-Path $p $exe
if (Test-Path $c) { return $c }
}
throw "qemu-system-x86_64 not found on PATH. Install QEMU, or pass -Qemu <path>."
}
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$log = Join-Path $root 'build\splashshot.log'
$log = Join-Path $root 'build/splashshot.log'
$dir = Join-Path $root $OutDir
Remove-Item -Recurse -Force $dir -ErrorAction SilentlyContinue
@ -30,7 +53,11 @@ New-Item -ItemType Directory -Force $dir | Out-Null
Remove-Item -Force $log -ErrorAction SilentlyContinue
$hda = Join-Path $root 'schos.img'
$hdb = Join-Path $root 'build\fs.img'
# The root filesystem. SchFS is the only root there is: the kernel mounts
# device 1 in forkret() and panics if it is not a SchFS volume, so this is
# not a choice and there is no -SchFS switch any more. It used to default to
# build/fs.img, which stopped being bootable the moment SchFS became root.
$hdb = Join-Path $root 'build/schfs.img'
$monPort = 55556 # not crashshot's port, so the two can run back to back
@ -42,7 +69,7 @@ $psi.Arguments = @(
# developer already has open would otherwise make this fail with "Failed to
# get write lock" -- and a capture script is exactly the thing you want to
# run without first shutting down what you were looking at. Copying was the
# first fix and it meant duplicating build\fs.img, all 153 MB of it, on
# first fix and it meant duplicating build/fs.img, all 153 MB of it, on
# every run. -snapshot keeps writes in a temporary overlay, so the originals
# are untouched either way.
"-drive file=`"$hda`",format=raw,index=0,media=disk,file.locking=off"

View file

@ -14,23 +14,48 @@
# shell. screendump writes a PPM; the PNG conversion is optional and skipped if
# ImageMagick is not around.
#
# tools\crashshot.ps1 crash the ramdisk-root build
# tools\crashshot.ps1 -SchFS with a SchFS volume attached
# tools/crashshot.ps1 crash the ramdisk-root build
param(
[switch]$SchFS,
[int]$BootSeconds = 20,
[string]$Out = "build\textshot.ppm",
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
[string]$Out = "build/textshot.ppm",
[string]$Qemu = (Find-Qemu)
)
# QEMU, on whichever host this is.
#
# PowerShell 7 runs on Linux, macOS and the BSDs as well as Windows, so these
# scripts are usable from all of them -- but the old default was a hardcoded
# scoop path under $env:USERPROFILE, which exists on exactly one of those. PATH
# first, because a package-managed qemu is on it everywhere; the scoop location
# is only a fallback for the Windows install that does not add itself to PATH.
function Find-Qemu {
$exe = if ($IsWindows -or $env:OS -eq 'Windows_NT') { 'qemu-system-x86_64.exe' }
else { 'qemu-system-x86_64' }
$onPath = Get-Command $exe -ErrorAction SilentlyContinue
if ($onPath) { return $onPath.Source }
if ($env:USERPROFILE) {
$scoop = Join-Path (Join-Path $env:USERPROFILE 'scoop/apps/qemu/current') $exe
if (Test-Path $scoop) { return $scoop }
}
foreach ($p in @('/usr/bin', '/usr/local/bin', '/opt/homebrew/bin')) {
$c = Join-Path $p $exe
if (Test-Path $c) { return $c }
}
throw "qemu-system-x86_64 not found on PATH. Install QEMU, or pass -Qemu <path>."
}
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$hda = Join-Path $root 'schos.img'
$hdb = if ($SchFS) { Join-Path $root 'build\schfs.img' } else { Join-Path $root 'build\fs.img' }
$log = Join-Path $root 'build\crashshot.log'
# The root filesystem. SchFS is the only root there is: the kernel mounts
# device 1 in forkret() and panics if it is not a SchFS volume, so this is
# not a choice and there is no -SchFS switch any more. It used to default to
# build/fs.img, which stopped being bootable the moment SchFS became root.
$hdb = Join-Path $root 'build/schfs.img'
$log = Join-Path $root 'build/crashshot.log'
$ppm = Join-Path $root $Out
$mon = Join-Path $root 'build\qemu-mon.sock'
$mon = Join-Path $root 'build/qemu-mon.sock'
Remove-Item -Force $log, $ppm -ErrorAction SilentlyContinue

View file

@ -7,19 +7,46 @@
# framebuffer. So the serial transcript can never tell you whether the escape
# parser works -- it contains the raw bytes either way. Only a picture can.
#
# tools\ttyshot.ps1
# tools/ttyshot.ps1
param(
[int]$BootSeconds = 22,
[string]$Out = "build\ttyshot.ppm",
[string]$Qemu = "$env:USERPROFILE\scoop\apps\qemu\current\qemu-system-x86_64.exe"
[string]$Out = "build/ttyshot.ppm",
[string]$Qemu = (Find-Qemu)
)
# QEMU, on whichever host this is.
#
# PowerShell 7 runs on Linux, macOS and the BSDs as well as Windows, so these
# scripts are usable from all of them -- but the old default was a hardcoded
# scoop path under $env:USERPROFILE, which exists on exactly one of those. PATH
# first, because a package-managed qemu is on it everywhere; the scoop location
# is only a fallback for the Windows install that does not add itself to PATH.
function Find-Qemu {
$exe = if ($IsWindows -or $env:OS -eq 'Windows_NT') { 'qemu-system-x86_64.exe' }
else { 'qemu-system-x86_64' }
$onPath = Get-Command $exe -ErrorAction SilentlyContinue
if ($onPath) { return $onPath.Source }
if ($env:USERPROFILE) {
$scoop = Join-Path (Join-Path $env:USERPROFILE 'scoop/apps/qemu/current') $exe
if (Test-Path $scoop) { return $scoop }
}
foreach ($p in @('/usr/bin', '/usr/local/bin', '/opt/homebrew/bin')) {
$c = Join-Path $p $exe
if (Test-Path $c) { return $c }
}
throw "qemu-system-x86_64 not found on PATH. Install QEMU, or pass -Qemu <path>."
}
$ErrorActionPreference = 'Stop'
$root = Split-Path $PSScriptRoot -Parent
$hda = Join-Path $root 'schos.img'
$hdb = Join-Path $root 'build\fs.img'
$log = Join-Path $root 'build\ttyshot.log'
# The root filesystem. SchFS is the only root there is: the kernel mounts
# device 1 in forkret() and panics if it is not a SchFS volume, so this is
# not a choice and there is no -SchFS switch any more. It used to default to
# build/fs.img, which stopped being bootable the moment SchFS became root.
$hdb = Join-Path $root 'build/schfs.img'
$log = Join-Path $root 'build/ttyshot.log'
$ppm = Join-Path $root $Out
$monPort = 55571