foundry
Foundry OS: the operating system built on the Rustbelt kernel
| author | Grok Bot <grokbot@localhost> | 2026-10-31 19:22:37 -0700 |
|---|---|---|
| commit | baf7b2d1a4ccb7e2240203ce9b7601225dd6bf12 | |
| parent | 01c85e80bd731f0b5b366d61b2b27c1314fb297c | |
| tree | browse files at this commit | |
ports/dash: fetch (SHA256-pinned, mirror list) and build dash 0.5.12 static-PIE with foundry-cc ports/fetch.sh NAME tries each URL in NAME.url until one gives the pinned SHA256. Upstream answered HTTP 500 today; Debian's dash_0.5.12.orig.tar.gz is byte-identical and is the fallback. Plain configure + make, no patches.
| M | ports/README.md | +21 -3 |
| A | ports/dash/build.sh | +36 -0 |
| M | ports/dash/dash.url | +1 -0 |
| A | ports/dash/patches/.keep | +0 -0 |
| A | ports/fetch.sh | +35 -0 |
5 files changed, 93 insertions, 3 deletions
@@ -6,7 +6,7 @@ BSD ports trees do it: ``` ports/<name>/ ├── <name>.sha256 the pinned release tarball: "SHA256 file-name"-├── <name>.url where to download it (into the git-ignored cache/)+├── <name>.url where to download it, one URL per line: upstream, then mirrors ├── patches/ our changes, applied in order (0001-*.patch, ...) └── build.sh unpack -> patch -> CC=toolchain/foundry-cc configure -> make -> install into out/staging ```@@ -17,8 +17,26 @@ docs/porting.md). No tarball is ever committed; `cache/` is git-ignored and every download is checked against the SHA256 here. -Status (M1): only the pin for **dash 0.5.12** exists. It becomes-`/bin/sh` for POSIX scripts in M3 (the interactive shell stays `rbsh`).+`ports/fetch.sh NAME` downloads into `cache/` (trying each URL until one+gives the pinned SHA256); `make ports` fetches and builds every port listed+in `FOUNDRY_PORTS` (`config.mk`) and the image gets each one as `/bin/NAME`.++## dash 0.5.12++The first port: `CC=toolchain/foundry-cc ./configure --host=x86_64-linux-musl && make`,+no patches needed. About 216 KB, a static-PIE. Installed as **`/bin/dash`**,+*not* `/bin/sh`: the kernel starts `/bin/sh` as its shell, and that stays+`rbsh` until kernel request K5 (contract v2); then dash becomes `/bin/sh`+for POSIX scripts while `rbsh` stays the login shell. `make test` runs+`dash /mnt/disk0/scripts/dash-test.sh` (15 checks: arithmetic, functions,+case, globbing, pipes into our Rust tools, redirections, here-documents,+background jobs + `wait`, `trap`, ...).++Download note: upstream (gondor.apana.org.au) answered HTTP 500 on+2026-10-31; Debian's `dash_0.5.12.orig.tar.gz` is byte-identical (same+SHA256) and is the second URL.++Later: **sbase** (M4) and **busybox** (M5). Later: **sbase** (M4) and **busybox** (M5). Their applets go to `/usr/lib/busybox`, *off* the default `PATH`, so the Rust tools stay the default (see docs/plan.md).
@@ -0,0 +1,36 @@+#!/usr/bin/env bash+# Build dash (the Debian Almquist shell, a small POSIX sh) for Foundry OS:+# unpack the cached tarball, apply patches/*.patch in order, then the+# ordinary autoconf steps with our compiler:+# CC=toolchain/foundry-cc ./configure --host=x86_64-linux-musl && make+# foundry-cc makes a static-PIE against our musl, which Rustbelt runs as is.+# The result is installed as /bin/dash. It is NOT /bin/sh yet: the kernel+# starts /bin/sh as its shell, and that stays rbsh until kernel request K5.+#+# Usage: ports/dash/build.sh CACHE_DIR BUILD_DIR OUT_FILE+set -euo pipefail+HERE=$(cd "$(dirname "$0")" && pwd)+ROOT=$(cd "$HERE/../.." && pwd)+CACHE=$(realpath "$1") BUILD=$(realpath -m "$2") OUTFILE=$(realpath -m "$3")+read -r _ file < "$HERE/dash.sha256"+rm -rf "$BUILD" && mkdir -p "$BUILD"+tar -xzf "$CACHE/$file" -C "$BUILD"+src=$BUILD/${file%.tar.gz}+for p in "$HERE"/patches/*.patch; do+ [ -e "$p" ] || continue+ echo "[dash] applying $(basename "$p")"; patch -d "$src" -p1 < "$p"+done+cd "$src"+# --host makes configure name the target (we are cross-building for+# Rustbelt), but our binaries also run on the build machine, so configure's+# test programs still work.+CC=$ROOT/toolchain/foundry-cc CFLAGS="-O2" \+ ./configure --host=x86_64-linux-musl > "$BUILD/configure.log"+make -j"$(nproc)" > "$BUILD/make.log" 2>&1 || { tail -30 "$BUILD/make.log"; exit 1; }+mkdir -p "$(dirname "$OUTFILE")"+cp src/dash "$OUTFILE"+strip --strip-debug "$OUTFILE"+if readelf -l "$OUTFILE" | grep -q INTERP; then+ echo "[dash] $OUTFILE has a PT_INTERP: not a static-PIE"; exit 1+fi+echo "[dash] built $OUTFILE ($(stat -c %s "$OUTFILE") bytes, $(readelf -h "$OUTFILE" | awk '/Type:/{print $2}'), no PT_INTERP)"
@@ -1 +1,2 @@ http://gondor.apana.org.au/~herbert/dash/files/dash-0.5.12.tar.gz+https://deb.debian.org/debian/pool/main/d/dash/dash_0.5.12.orig.tar.gz
@@ -0,0 +1,35 @@+#!/usr/bin/env bash+# Download a port's release tarball into the download cache (default cache/)+# and check it against the SHA256 pinned in ports/NAME/NAME.sha256. Nothing+# downloaded is ever committed: cache/ is git-ignored.+#+# NAME.url lists one or more download URLs, one per line, tried in order+# (upstream first, then mirrors). The SHA256 decides, not the URL: a mirror+# copy is only kept if it is byte-for-byte the pinned release.+#+# Offline? Put the tarball in cache/ yourself (any copy with the right+# SHA256 is fine).+#+# Usage: ports/fetch.sh NAME [CACHE_DIR]+set -euo pipefail+HERE=$(cd "$(dirname "$0")" && pwd)+NAME=$1 CACHE=${2:-cache}+mkdir -p "$CACHE"+read -r sum file < "$HERE/$NAME/$NAME.sha256"+dest=$CACHE/$file+if [ ! -f "$dest" ]; then+ while read -r url; do+ [ -n "$url" ] || continue+ echo "[$NAME] downloading $url"+ if curl -fsSL --retry 2 -m 120 -o "$dest.part" "$url" &&+ echo "$sum $dest.part" | sha256sum -c --quiet - 2>/dev/null; then+ mv "$dest.part" "$dest"; break+ fi+ echo "[$NAME] failed or wrong SHA256, trying the next URL"; rm -f "$dest.part"+ done < "$HERE/$NAME/$NAME.url"+fi+if echo "$sum $dest" | sha256sum -c --quiet -; then+ echo "[$NAME] $dest: SHA256 OK"+else+ echo "[$NAME] $dest: SHA256 MISMATCH -- delete it and try again"; exit 1+fi