foundry
Foundry OS: the operating system built on the Rustbelt kernel
4635 bytes · raw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | # 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. The
kernel boots and runs the shell from it.
## Quick start
```sh
make # build out/foundry.img (the same as `make image`)
make test # boot it headless in QEMU and run the shell 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, the kernel's test fixtures, assembles `out/staging/`, and writes `out/foundry.img` |
| `make rust` | `cargo build --release` in `rust/` |
| `make fixtures` | builds the kernel's ABI test programs from the pinned kernel source |
| `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) |
| `make test` | headless boot, self-test, ~90 expected-output checks; exit 0 = pass |
| `make test-reference` | the same test on the kernel's *own* disk image (the baseline) |
| `make compare` | compares our image with the kernel's, file by file |
| `make musl` | downloads (into `cache/`) and builds musl into `out/sysroot`; then `toolchain/foundry-cc` builds static-PIE C programs (M2) |
| `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)
│ ├── rbsh/ the shell (installed as /bin/sh for now)
│ ├── 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
├── rootfs/ files copied onto the disk as they are (readme, notes, the self-test)
│ └── etc/ passwd, hosts... for the later ext2 root (not in the image yet)
├── toolchain/ foundry-cc (gcc + musl, static-PIE); musl/ pinned by SHA256, downloaded into cache/
├── c/ our own C programs (M2)
├── ports/ other people's C programs, one directory each (dash first)
├── scripts/ mkimage, build-kernel, run-qemu, run-headless, compare-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](docs/boot-contract.md) says what the image must
contain. QEMU gets our image as its first virtio disk, the kernel mounts it at
`/mnt/disk0` (the shell calls it drive `B:`) and runs `/mnt/disk0/bin/sh`.
We build against **one exact kernel commit** (`KERNEL_REV` in `config.mk`,
now `5291332` = Rustbelt 0.20.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](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](docs/plan.md) for
what comes next and [docs/proposal.md](docs/proposal.md) for the full
background.
New to these words? **[docs/glossary.md](docs/glossary.md)** explains
sysroot, static-PIE, subtree, GPT, musl and the rest.
|