71 lines
2.4 KiB
Markdown
71 lines
2.4 KiB
Markdown
# Rust on MontaukOS
|
|
|
|
Phase 1: `no_std` + `alloc` programs, cross-compiled from Linux with a
|
|
stock nightly toolchain and a custom target spec. No compiler fork.
|
|
|
|
## Setup (once)
|
|
|
|
```bash
|
|
curl --proto '=https' -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none
|
|
~/.cargo/bin/rustup toolchain install nightly --component rust-src
|
|
```
|
|
|
|
`rust-toolchain.toml` selects nightly + `rust-src` for this directory.
|
|
`make programs` builds the Rust programs when that toolchain is present
|
|
and prints a notice and skips them otherwise. It never downloads a toolchain
|
|
(`RUSTUP_AUTO_INSTALL=0`).
|
|
|
|
## Building
|
|
|
|
```bash
|
|
make -C programs rust # cargo build --release, copies to bin/os/*.elf
|
|
cd programs/rust && cargo build --release
|
|
```
|
|
|
|
Output: `target/x86_64-unknown-montauk/release/<name>`, installed as
|
|
`programs/bin/os/<name>.elf`. Add new binaries to `RUST_PROGRAMS` in
|
|
`programs/GNUmakefile` and to the workspace `members`.
|
|
|
|
## Layout
|
|
|
|
| Path | Purpose |
|
|
|------|---------|
|
|
| `x86_64-unknown-montauk.json` | Target spec: static non-PIE ET_EXEC, no red zone, local-exec TLS, panic=abort |
|
|
| `.cargo/config.toml` | `-Zbuild-std=core,alloc`, linker = `x86_64-montauk-gcc` |
|
|
| `montauk-rt/` | Runtime: syscalls, allocator, `print!`, argv, threads, futex `Mutex`, panic handler |
|
|
| `rusthello/` | Smoke test (`rusthello`, `rusthello panic`, `rusthello panic-thread`) |
|
|
|
|
The GCC driver links crt1/crti/crtbegin, the libc and libgcc from
|
|
`toolchain/sysroot`, the same as ports. After changing `programs/lib/libc`,
|
|
re-run `toolchain/build-montauk-toolchain.sh` so Rust programs pick it up.
|
|
|
|
Syscall numbers and status codes are generated at build time by
|
|
`montauk-rt/build.rs` from `programs/include/Api/Syscall.hpp` and
|
|
`kernel/src/Common/StatusCodes.hpp`, so there is nothing to keep in sync by hand.
|
|
|
|
## Writing a program
|
|
|
|
```rust
|
|
#![no_std]
|
|
#![no_main]
|
|
extern crate alloc;
|
|
|
|
montauk_rt::entry!(main);
|
|
|
|
fn main() -> i32 {
|
|
montauk_rt::println!("hello from Rust");
|
|
0
|
|
}
|
|
```
|
|
|
|
## Limits (Phase 1)
|
|
|
|
- No `std`. No `std::fs`, `std::net`, `std::process` or `std::thread`; use
|
|
`montauk_rt` equivalents where they exist.
|
|
- `panic = "abort"`. A panic on any thread prints the message and kills the
|
|
whole process.
|
|
- Thread stacks are owned by the `JoinHandle`. An unjoined thread leaks its stack.
|
|
|
|
Phase 2 (a forked rustc at `~/dev/mtk/rust` with a native `target_os =
|
|
"montauk"` std) replaces the JSON spec with a built-in target.
|