foundry
Foundry OS: the operating system built on the Rustbelt kernel
git clone https://git.rustbelt.dev/foundry| Branch | Commit message | Author | Age |
|---|---|---|---|
| main | docs/plan.md: long-term track (after M5): a self-hosted Rust toolchain on Foundry OS, in 3 stages (not started) | Grok Bot | 21 minutes ago |
Recent commits
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
| Target | What it does |
|---|---|
make image | builds 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-v1 | the old one-partition FAT32 image, out/foundry-v1.img (contract v1) |
make rust | cargo build --release in rust/ (rbsh, init, the tools) |
make fixtures | builds the kernel's ABI test programs from the pinned kernel source |
make cprogs | builds our C programs (c/: hello-musl, fprobe, orphan) as static-PIEs with toolchain/foundry-cc |
make ports | downloads (SHA256-checked, into cache/) and builds the ports (dash) the same way |
make kernel | builds the pinned Rustbelt kernel into out/kernel-target |
make run | boots the image in a QEMU window (NOGRAPHIC=1 for serial only; KEEP=1 keeps what you write to the disk) |
make test | headless 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-v1 | the contract-v1 test: the kernel runs the shell self-test on out/foundry-v1.img (~100 checks) |
make test-reference | the v1 test on the kernel's own disk image (the baseline) |
make compare | compares our v1 image with the kernel's, file by file |
make rbsh-test | host unit tests for rbsh's parser and drive letters (no QEMU) |
make k1-check | builds the kernel with RUSTBELT_DISK0=out/foundry.img and checks it uses our image |
make musl | downloads (into cache/) and builds musl into out/sysroot; make cprogs/make ports run it when needed |
make clean | rm -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.