RustForge

foundry

Foundry OS: the operating system built on the Rustbelt kernel

foundry / rust / rbrt / README.md
1667 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
# rbrt: the Foundry OS Rust runtime

`ulib.rs` is the tiny runtime every Foundry OS Rust program includes:
raw Rustbelt/Linux syscall wrappers, `print!`/`println!`/`eprintln!`, a
`brk` heap (so `Vec` and `String` work), the `_start` entry point that calls
the program's `fn main() -> i64`, and the panic handler.

Since milestone M1b it is a real **library crate** (package `rbrt`, imported
under the shorter name `ulib`). A program uses it like this:

```toml
# Cargo.toml of the program's package
[dependencies]
ulib = { package = "rbrt", path = "../rbrt" }
```

```rust
#![no_std]
#![no_main]

#[macro_use]           // brings in print!, println!, eprintln!
extern crate ulib;
ulib::entry!(main);    // tells _start which function is main

use ulib::*;           // the syscall wrappers: open, read, write, ...

fn main() -> i64 {
    println!("hello");
    0                  // the exit code
}
```

How the pieces fit: `_start` (in `ulib.rs`) reads argc/argv/envp from the
stack and calls a function named `rbrt_main`. `ulib::entry!(main)` defines
`rbrt_main` in your program and makes it call your `main`. The panic handler
and the heap allocator (`#[global_allocator]`) also live in the crate, so a
program gets them just by depending on it. (Before M1b, every program pulled
the file in as a module with `#[path = "...ulib.rs"] mod ulib;`; the kernel
repo still does that for its own test programs.)

`build.rs` here is the build script shared by all packages: it adds
`-T rust/link.ld` to the link.

The kernel repo keeps its own frozen copy of `ulib.rs` for its ABI test
programs (hello, forktest, ...), so the two copies may drift apart; that is
intended.