foundry
Foundry OS: the operating system built on the Rustbelt kernel
| author | Grok Bot <grokbot@localhost> | 2026-10-31 19:18:31 -0700 |
|---|---|---|
| commit | eeb17191ca987aed8a182690ff99acbfd3360053 | |
| parent | 3219ac028e84cecb701829744852c66efa89e4e6 | |
| tree | browse files at this commit | |
M2: build c/ with foundry-cc, put hello-musl and fprobe in /bin, check them in make test - make cprogs: toolchain/foundry-cc (static-PIE); builds musl first if needed. - selftest.sh: a marked 'Foundry OS' block at the end runs both programs. - scripts/expect-foundry.txt: their expected lines (EXTRA_EXPECT for make test only; test-reference keeps the kernel's own list). - compare-image.sh: leaves FOUNDRY_BIN out of the list comparison and cuts the Foundry OS block out of selftest.sh before comparing it.
| M | Makefile | +29 -9 |
| M | config.mk | +6 -0 |
| M | rootfs/scripts/selftest.sh | +8 -0 |
| M | scripts/compare-image.sh | +12 -3 |
| A | scripts/expect-foundry.txt | +20 -0 |
5 files changed, 75 insertions, 12 deletions
@@ -14,9 +14,14 @@ KSRC := $(OUT)/kernel-src KTARGET := $(OUT)/kernel-target KBOOT := $(OUT)/kernel/bootimage.bin KBOOT_HL := $(OUT)/kernel/bootimage-headless.bin+SYSROOT := $(OUT)/sysroot+FCC := $(CURDIR)/toolchain/foundry-cc+C_OUT := $(OUT)/c+# Everything in /bin, in order: the kernel's list, then Foundry OS's own.+ALL_BIN := $(BIN_ORDER) $(FOUNDRY_C) .DEFAULT_GOAL := image-.PHONY: help image rust fixtures staging kernel kernel-src run test test-reference compare musl clean distclean+.PHONY: help image rust fixtures cprogs staging kernel kernel-src run test test-reference compare musl clean distclean help: @echo "Foundry OS (userland for the Rustbelt kernel $(KERNEL_VERSION) @ $(KERNEL_REV))"@@ -24,13 +29,14 @@ help: @echo " make / make image build out/$(IMAGE_NAME), the disk image (contract $(CONTRACT))" @echo " make rust cargo build the Rust programs in rust/" @echo " make fixtures build the kernel's ABI test programs from the pinned kernel"+ @echo " make cprogs build our C programs (c/) as static-PIEs with toolchain/foundry-cc" @echo " make staging assemble out/staging (rootfs/ + /bin)" @echo " make kernel build the pinned kernel into out/kernel-target" @echo " make run boot the image in a QEMU window" @echo " make test headless boot + the shell self-test + expected-line checks" @echo " make test-reference the same headless test, but booting the kernel's own disk.img (baseline)" @echo " make compare compare out/$(IMAGE_NAME) with the kernel's own disk.img"- @echo " make musl fetch (cache/) + build musl $(MUSL_VERSION) into out/sysroot (not in the image yet)"+ @echo " make musl fetch (cache/) + build musl $(MUSL_VERSION) into out/sysroot" @echo " make clean rm -rf out (distclean also removes cache/)" # ---- the pinned kernel -------------------------------------------------------@@ -47,18 +53,27 @@ rust: fixtures: kernel-src scripts/build-fixtures.sh $(KSRC) $(FIXTURES) "$(FIXTURE_RUST)" "$(FIXTURE_C)" "$(FIXTURE_MUSL)" +# Our own C programs: gcc + our musl, static-PIE (docs/porting.md).+cprogs: $(SYSROOT)/lib/musl-pie.specs+ mkdir -p $(C_OUT)+ for p in $(FOUNDRY_C); do \+ $(FCC) -O2 -Wall -Wextra -pthread -Wl,--build-id=none c/$$p.c -o $(C_OUT)/$$p || exit 1; \+ done+ @echo "[cprogs] built $(FOUNDRY_C) into $(C_OUT)"+ # ---- the image --------------------------------------------------------------- # Contract v1: rootfs/ minus etc/ (etc/ is for the contract-v2 ext2 root, # see docs/plan.md) goes to the top of the FAT32 volume, programs to /bin.-staging: rust fixtures+staging: rust fixtures cprogs rm -rf $(STAGING) && mkdir -p $(STAGING)/bin cd rootfs && for e in $$(ls -A); do [ "$$e" = etc ] && [ "$(CONTRACT)" = v1 ] && continue; cp -r "$$e" $(STAGING)/; done for p in $(filter-out sh,$(RUST_PROGRAMS)); do cp $(RUST_OUT)/$$p $(STAGING)/bin/; done cp $(RUST_OUT)/rbsh $(STAGING)/bin/sh # contract v1: the kernel runs /mnt/disk0/bin/sh cp $(FIXTURES)/* $(STAGING)/bin/+ for p in $(FOUNDRY_C); do cp $(C_OUT)/$$p $(STAGING)/bin/; done image: staging- scripts/mkimage.sh $(STAGING) $(IMAGE) $(IMAGE_MIB) $(IMAGE_LABEL) "$(BIN_ORDER)"+ scripts/mkimage.sh $(STAGING) $(IMAGE) $(IMAGE_MIB) $(IMAGE_LABEL) "$(ALL_BIN)" # ---- booting ---------------------------------------------------------------- run: image kernel@@ -68,21 +83,26 @@ run: image kernel TEST_ENV := KERNEL_BANNER="$(KERNEL_BANNER)" KERNEL_VERSION=$(KERNEL_VERSION) test: image kernel- $(TEST_ENV) BIN_COUNT=$(words $(BIN_ORDER)) \+ $(TEST_ENV) BIN_COUNT=$(words $(ALL_BIN)) EXTRA_EXPECT=scripts/expect-foundry.txt \ scripts/run-headless.sh $(IMAGE) $(KBOOT_HL) $(KTARGET) $(OUT) -# The baseline: the kernel's own disk.img through the very same checks.+# The baseline: the kernel's own disk.img through the very same checks+# (without Foundry OS's own programs and expected lines, which it lacks). test-reference: kernel $(TEST_ENV) BIN_COUNT=$(words $(BIN_ORDER)) \ scripts/run-headless.sh $(KTARGET)/disk.img $(KBOOT_HL) $(KTARGET) $(OUT)/reference compare: image kernel- scripts/compare-image.sh $(IMAGE) $(KTARGET)/disk.img $(OUT)+ FOUNDRY_BIN="$(FOUNDRY_C)" scripts/compare-image.sh $(IMAGE) $(KTARGET)/disk.img $(OUT) -# ---- toolchain (M2 groundwork; not used by the v1 image) ---------------------+# ---- toolchain ---------------------------------------------------------------+# musl is built once; delete out/sysroot (or run `make musl`) to rebuild it. musl: toolchain/musl/fetch.sh cache- toolchain/musl/build.sh cache $(OUT)/musl-build $(OUT)/sysroot+ toolchain/musl/build.sh cache $(OUT)/musl-build $(SYSROOT)++$(SYSROOT)/lib/musl-pie.specs: toolchain/musl/musl.sha256 toolchain/musl/musl-pie.specs.in toolchain/musl/build.sh+ $(MAKE) musl clean: rm -rf out
@@ -53,5 +53,11 @@ BIN_ORDER := sh ls cat wc grep mkdir rm touch cp sleep \ rawabi vdsotest piehello piethreads dynhello remaptest \ exechello execthreads timerfdtest +# Foundry OS's own C programs (c/NAME.c), built with toolchain/foundry-cc+# as static-PIEs against our musl (milestone M2). They go to /bin after the+# programs above, and the self-test runs them (rootfs/scripts/selftest.sh,+# the "Foundry OS" block; expected lines in scripts/expect-foundry.txt).+FOUNDRY_C := hello-musl fprobe+ # ---- Toolchain pins (downloaded into cache/, checked by SHA256) ----------- MUSL_VERSION ?= 1.2.5
@@ -117,4 +117,12 @@ nosuchprogram cd Q: cd A:/tmp pwd+# ---- Foundry OS ----+# Foundry OS's own programs (milestone M2): C on musl, built by+# toolchain/foundry-cc as static-PIEs. hello-musl prints one line; fprobe+# checks the C library's view of the kernel (files, processes, signals,+# threads, mmap, clocks, timerfd) and prints a summary line at the end.+hello-musl+fprobe+# ---- end Foundry OS ---- exit 0
@@ -9,17 +9,26 @@ # in bytes from the kernel's single-file rustc builds (Cargo adds crate # metadata), so only list equality and non-program files fail the check. #-# Usage: scripts/compare-image.sh OURS KERNELS OUT_DIR+# Since M2 our image has more than the kernel's: Foundry OS's own programs+# (env FOUNDRY_BIN, left out of the list comparison) and a "Foundry OS"+# block in scripts/selftest.sh (cut out before comparing that file).+#+# Usage: [FOUNDRY_BIN="prog ..."] scripts/compare-image.sh OURS KERNELS OUT_DIR set -euo pipefail+fail=0 OURS=$1 THEIRS=$2 OUT=$(realpath -m "$3")/compare export MTOOLS_SKIP_CHECK=1 rm -rf "$OUT" && mkdir -p "$OUT/ours" "$OUT/kernel" mcopy -s -n -i "$OURS@@1M" '::/*' "$OUT/ours/" mcopy -s -n -i "$THEIRS@@1M" '::/*' "$OUT/kernel/" -(cd "$OUT/ours/bin" && ls | LC_ALL=C sort) > "$OUT/bin-ours.txt"+(cd "$OUT/ours/bin" && ls | LC_ALL=C sort) > "$OUT/bin-ours-all.txt"+grep -vxF -f <(printf '%s\n' ${FOUNDRY_BIN:-} '') "$OUT/bin-ours-all.txt" > "$OUT/bin-ours.txt" || true+echo "== Foundry OS's own programs (not in the kernel's image): ${FOUNDRY_BIN:-none}"+for p in ${FOUNDRY_BIN:-}; do [ -f "$OUT/ours/bin/$p" ] || { echo " MISSING /bin/$p"; fail=1; }; done+# Our selftest.sh = the kernel's + a "Foundry OS" block; compare without it.+sed -i '/^# ---- Foundry OS ----$/,/^# ---- end Foundry OS ----$/d' "$OUT/ours/scripts/selftest.sh" (cd "$OUT/kernel/bin" && ls | LC_ALL=C sort) > "$OUT/bin-kernel.txt"-fail=0 echo "== /bin program list: ours $(wc -l < "$OUT/bin-ours.txt"), kernel $(wc -l < "$OUT/bin-kernel.txt")" if diff -u "$OUT/bin-kernel.txt" "$OUT/bin-ours.txt"; then echo " same list"
@@ -0,0 +1,20 @@+# Lines Foundry OS's own part of the self-test must print (the "Foundry OS"+# block at the end of rootfs/scripts/selftest.sh). `make test` passes this+# file to scripts/run-headless.sh as EXTRA_EXPECT; `make test-reference`+# (the kernel's own image) doesn't. One line per check, matched as a fixed+# string anywhere in the serial log. @KERNEL_VERSION@ = config.mk's value.+# Blank lines and lines starting with # are skipped.++# hello-musl: a static-PIE C program on our musl.+hello from musl on Rustbelt @KERNEL_VERSION@ (Foundry OS, static-PIE)++# fprobe (c/fprobe.c): a few key checks by name, then the summary, which+# also pins the number of checks (so none can silently go missing).+fprobe: Foundry OS libc self-check on Rustbelt @KERNEL_VERSION@+ static-PIE: ET_DYN without PT_INTERP ok+ 4 threads x 20000 mutex increments = 80000 ok+ timerfd one-shot: read blocks ~150 ms, count 1 ok+ timerfd 60 ms interval: 5-14 expirations in 700 ms ok+ timerfd wakes epoll_wait ok+ TFD_TIMER_CANCEL_ON_SET -> EINVAL (Rustbelt) ok+fprobe: all 40 checks passed