RustForge

foundry

Foundry OS: the operating system built on the Rustbelt kernel

foundry / docs / boot-contract.md
3100 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
# The boot contract: what the kernel expects from the Foundry OS image

The Rustbelt kernel and Foundry OS live in different repos. This page is the
whole agreement between them. The kernel never needs to know *how* the
image was built, only that it follows the contract.

## Contract v1: "today, written down" (in use now)

Pinned kernel: Rustbelt 0.21.0, commit 50476f4 (was 0.20.0, 5291332). No kernel change needed.

1. **Where.** The OS image is the **first virtio-blk disk** QEMU is given.
   The kernel mounts it at `/mnt/disk0` (drive `B:` in rbsh).
2. **Format.** A **GPT** partition table with one partition starting at
   sector 2048 (1 MiB), type "Microsoft basic data", formatted **FAT32**,
   volume label `TYLERDISK` (kept from the kernel for now). 64 MiB total.
3. **Contents.**
   - **`/bin/sh`**: the program the kernel starts. In Foundry OS this is
     **rbsh** (crate `rust/rbsh`, binary `rbsh`), copied under the name `sh`.
   - `/scripts/selftest.sh`: the self-test, for headless kernels.
   - Programs live in `/bin`. Each is a **static** ELF: either a
     **static-PIE** (`ET_DYN` without `PT_INTERP`, since 0.19.0; what
     Foundry OS builds) or an `ET_EXEC` linked anywhere in user space,
     which since 0.20.0 starts at `0x40_0000`, so a plain `gcc -static`
     program at the usual `0x400000` runs (until 0.19.0 it had to be at
     or above `0x80_0040_0000`). Dynamic programs are refused.
4. **What the kernel provides.** `/` is a ramfs the kernel builds itself
   (with `/tmp`, `/dev`, `/proc`, `/mnt`). It runs `/mnt/disk0/bin/sh`
   with `PATH=/bin:/mnt/disk0/bin HOME=/ TERM=linux`, and restarts it when
   it exits. A headless kernel (`--features headless`) instead runs
   `sh /mnt/disk0/scripts/selftest.sh` once and powers QEMU off with the
   shell's status: QEMU exit code **33 = pass**, 35 = fail.
5. **Other disks belong to the kernel.** The ext2, exFAT and btrfs test
   disks are built by the kernel's build into `out/kernel-target`. Our run
   scripts attach them after our disk, so `C:`, `D:`, `E:` keep their letters.

Under v1 the image must also carry the kernel's ABI test programs
(`forktest`, `rawabi`, ...), because the self-test runs them. They are
built from the pinned kernel source (`make fixtures`); see
[kernel-requests.md]kernel-requests.md for how that dependency goes away.

## Contract v2: a real root file system (planned, needs kernel request K5)

1. The OS image is GPT with a partition of type **Linux root (x86-64)**,
   `4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709` (the freedesktop *Discoverable
   Partitions* rule), formatted **ext2**. The kernel mounts it at **`/`**,
   so `A:` = `/` is the OS disk.
2. The kernel keeps a ramfs at `/tmp`, devfs at `/dev`, and mounts the other
   disks at `/mnt/diskN`.
3. The kernel runs the first that exists of `/sbin/init`, `/bin/init`,
   `/bin/sh` as **pid 1**, does not respawn it, and hands orphans to it.
   Headless: `["init", "selftest"]`; pid 1's exit status ends QEMU.
4. Fallback: no root partition → behave as v1.

See [plan.md]plan.md for the disk layout we chose for v2.