RustForge

foundry

Foundry OS: the operating system built on the Rustbelt kernel

clone: git clone https://git.rustbelt.dev/foundry
BranchCommit messageAuthorAge
maindocs/plan.md: long-term track (after M5): a self-hosted Rust toolchain on Foundry OS, in 3 stages (not started)Grok Bot21 minutes ago

Recent commits

AgeCommit messageAuthorId
21 minutes agodocs/plan.md: long-term track (after M5): a self-hosted Rust toolchain on Foundry OS, in 3 stages (not started)Grok Bote2b25e53f8
22 minutes agoDocs: boot contract v2 (layout, init, drive letters and the share for beginners), M3 done, K12 (FAT dirty bit: no unmount on pid 1 exit)Grok Bot5a331c407d
22 minutes agomake test is contract v2 (init runs the self-test, host fsck + share read-back); make test-v1/image-v1 keep the old layout; compare uses v1Grok Botc8f1cf1102
22 minutes agoscripts/mkimage-v2.sh: one GPT disk with ext2 root, FAT32 data and single-FAT exFAT shareGrok Botd53297804f
22 minutes agoContract v2 trees: root/ (A:, /etc moved from rootfs/, v2 self-test + dash v2-test.sh), share/ (C:); dash-test.sh takes the bin dirGrok Bot12ef9f02ff
31 minutes agoscripts/exfat.py: read/fill an exFAT volume inside an image without mounting itGrok Bot4dc7c2e206
31 minutes agoc/orphan.c: check that an orphaned grandchild is adopted and reaped by init (pid 1)Grok Bot12674c45d0
31 minutes agorust/init: Foundry OS /sbin/init for boot contract v2 (rbsh on console + hvc0, respawn, orphan reaping, headless self-test with memory check)Grok Bot55604d879b
35 minutes agorbsh: C: is the share (/mnt/share) when mounted, disks take B:, D:, ...; getty prefers /bin/rbsh; host tests (make rbsh-test)Grok Bot8950fae6ee
38 minutes agoBump kernel pin to Rustbelt 0.21.0 (50476f4); add make k1-check (RUSTBELT_DISK0 gives a byte-identical disk.img)Grok Bot15035eada5

README.md

Foundry OS

Foundry OS is a small operating system that runs on the Rustbelt kernel, the way Ubuntu runs on Linux. The kernel (in its own repo, /workspace/rust-kernel) drives the hardware; Foundry OS is everything else: the shell rbsh, the tools (ls, cat, grep...), the network and system programs, and the disk image they live on.

This repo builds one file, out/foundry.img, a virtual hard disk with three parts (partitions): the system (drive A:, mounted at /), a data disk (B:) and a share for swapping files with other computers (C:). The kernel boots, mounts them, and runs our /sbin/init, which starts the shell.

Quick start

make            # build out/foundry.img (the same as `make image`)
make test       # boot it headless in QEMU: init runs the self-test
make run        # boot it in a QEMU window and play
make help       # every target

The first make test also builds the pinned kernel (a few minutes). You need the packages the kernel needs plus make (all already on the box): rustup (nightly), qemu-system-x86, dosfstools, mtools, fdisk, e2fsprogs, exfatprogs, btrfs-progs, musl-tools, gcc.

Make targets

TargetWhat it does
make imagebuilds the Rust programs, our C programs and ports, the kernel's test fixtures, assembles out/staging-v2/, and writes out/foundry.img (boot contract v2: ext2 root A:, FAT32 data B:, exFAT share C:; see docs/boot-contract.md)
make image-v1the old one-partition FAT32 image, out/foundry-v1.img (contract v1)
make rustcargo build --release in rust/ (rbsh, init, the tools)
make fixturesbuilds the kernel's ABI test programs from the pinned kernel source
make cprogsbuilds our C programs (c/: hello-musl, fprobe, orphan) as static-PIEs with toolchain/foundry-cc
make portsdownloads (SHA256-checked, into cache/) and builds the ports (dash) the same way
make kernelbuilds the pinned Rustbelt kernel into out/kernel-target
make runboots the image in a QEMU window (NOGRAPHIC=1 for serial only; KEEP=1 keeps what you write to the disk)
make testheadless boot: our /sbin/init runs the self-test (expected lines in scripts/expect-v2.txt), then the host fscks all three file systems and reads the share back; exit 0 = pass
make test-v1the contract-v1 test: the kernel runs the shell self-test on out/foundry-v1.img (~100 checks)
make test-referencethe v1 test on the kernel's own disk image (the baseline)
make comparecompares our v1 image with the kernel's, file by file
make rbsh-testhost unit tests for rbsh's parser and drive letters (no QEMU)
make k1-checkbuilds the kernel with RUSTBELT_DISK0=out/foundry.img and checks it uses our image
make musldownloads (into cache/) and builds musl into out/sysroot; make cprogs/make ports run it when needed
make cleanrm -rf out (make distclean also empties cache/)

What is where

foundry/
├── Makefile, config.mk   the build; config.mk pins the kernel commit
├── rust/                 the Rust programs (a Cargo workspace)
│   ├── init/             /sbin/init: the first program; starts shells, reaps orphans
│   ├── rbsh/             the shell, /bin/rbsh (drive letters A: B: C:)
│   ├── coreutils-rs/     ls cat wc grep mkdir rm touch cp sleep
│   ├── net/              ifconfig ping host fetch httpd
│   ├── sys/              getty tile random sysinfo
│   ├── rbrt/             the runtime every program includes (ulib.rs) + shared build.rs
│   └── link.ld           puts programs at address 0x80_0040_0000
├── root/                 the root file system, A: = / (etc/, the v2 self-test in scripts/)
├── rootfs/               the FAT32 data disk, B: = /mnt/disk0 (readme, notes; v1 self-test)
├── share/                the exFAT share, C: = /mnt/share (README.TXT)
├── toolchain/           foundry-cc (gcc + musl, static-PIE); musl/ pinned by SHA256, downloaded into cache/
├── c/                    our own C programs: hello-musl, fprobe (the libc self-check), orphan
├── ports/                other people's C programs, one directory each (dash: /bin/dash)
├── scripts/              mkimage(-v2), exfat.py, build-kernel, run-qemu, run-headless, check-v2-image...
├── docs/                 how it all fits together (start with docs/glossary.md)
├── out/                  everything built (git-ignored)
└── cache/                downloads (git-ignored)

How it fits with the kernel

The kernel repo and this repo meet in exactly one place: the disk image. docs/boot-contract.md says what the image must contain. QEMU gets our image as its first virtio disk; the kernel (0.21.0+) mounts the ext2 root partition at /, the FAT32 partition at /mnt/disk0 and the exFAT share at /mnt/share, and runs /sbin/init as process 1 (contract v2). make test-v1 still checks the old layout (contract v1: one FAT32 partition at /mnt/disk0, the kernel runs /mnt/disk0/bin/sh).

We build against one exact kernel commit (KERNEL_REV in config.mk, now 50476f4 = Rustbelt 0.21.0). The build exports that commit from the kernel repo's git store with git archive and compiles it in out/, so the kernel repo itself is never changed. To move to a newer kernel, follow docs/bumping-the-kernel.md.

Where this came from

The programs were in the kernel repo's user/ folder. They were brought here with git subtree split, which keeps their full history: try git log --follow rust/coreutils-rs/src/bin/ls.rs. The kernel keeps its ABI test programs (forktest, rawabi...), and for now the image still carries them because the self-test runs them. See docs/plan.md for what comes next and docs/proposal.md for the full background.

New to these words? docs/glossary.md explains sysroot, static-PIE, subtree, GPT, musl and the rest.