RustForge

foundry

Foundry OS: the operating system built on the Rustbelt kernel

foundry / docs / porting.md
2292 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
# Porting a C program to Foundry OS

*Status: groundwork only (milestone M2 adds the first C programs to the image).*

## The toolchain

Rustbelt 0.19.0 loads **static-PIE** programs (`ET_DYN` with no
`PT_INTERP`), so C programs need no special link tricks any more. Every C
program and port is built as a static-PIE:

```sh
make musl                                   # once: musl into out/sysroot (+ musl-pie.specs)
toolchain/foundry-cc -O2 c/hello-musl.c -o out/hello-musl
readelf -l out/hello-musl | grep INTERP     # must print nothing
```

`toolchain/foundry-cc` is three lines: `gcc -specs out/sysroot/lib/musl-pie.specs
-static-pie "$@"`. The specs file (`toolchain/musl/musl-pie.specs.in`, from
Clarke's 0.19.0 re-test) points gcc at our musl headers and libraries and,
for `-static-pie`, uses musl's self-relocating start file **`rcrt1.o`** and
links with **`--no-dynamic-linker`**.

**The gotcha:** the `musl-gcc` wrapper that musl itself installs (into
`out/sysroot/bin`) uses upstream `musl-gcc.specs`, and with `-static-pie`
that makes a *dynamic* PIE: it still has a `PT_INTERP`
(`/lib/ld-musl-x86_64.so.1`). Rustbelt refuses that with `ENOEXEC`. So use
`foundry-cc`, not that `musl-gcc`. Debian's `musl-gcc -static-pie`
(package `musl-tools`) also works; the kernel builds its own musl fixtures
with it.

The binaries also run on the Linux host, which is handy because configure
scripts run their test programs.

The old `rb-cc` wrapper from the proposal (crt1.o, `-Ttext-segment`,
`--defsym=_DYNAMIC`, `--no-relax`, for `ET_EXEC` at Rustbelt's high user
base) is retired. The kernel keeps one program built that way (`vdsotest`)
as a loader test.

## Adding a port

```
ports/<name>/<name>.sha256   "SHA256  <tarball>"
ports/<name>/<name>.url      where to download it
ports/<name>/patches/        0001-*.patch ...
ports/<name>/build.sh        unpack from cache/, patch, CC=toolchain/foundry-cc ./configure --host=x86_64-linux-musl,
                             make, install into out/staging (busybox/sbase: under /usr/lib/busybox)
```

Then boot it (`make test` / `make run`), try it, and note any missing
syscall in [syscall-gaps.md]syscall-gaps.md. `run --trace prog` in rbsh
shows every syscall, and `syscall_N(...) = -38 ENOSYS` marks the ones
Rustbelt doesn't have.