Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions docs/vocs/docs/pages/book/writing-apps/compiling-a-program.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
# Compiling a Program

Once you have written a program to be proven by OpenVM, you need to compile it in a way
which is compatible with OpenVM. This will involve **cross-compiling** the program by
building it for a machine architecture which differs from the machine performing the build.

To explain how this works for OpenVM, we will use the following key terms:

- **Host**: The machine architecture being used for building and proving. Though building and proving can be done on different machine architectures, they are both called **host** architectures since they are not the architecture used to specify the program.
- **Guest**: The machine architecture being used to express the program to be proven, which is the OpenVM runtime in this case. We refer to programs written to be proven by OpenVM as **guest programs**.
which is compatible with OpenVM. We refer to programs written to be proven by OpenVM as
**guest programs**, with the term coming from its usage in
[cross-compilation](/specs/reference/rust-toolchain) as explained in the specs.

## Building Guest Programs for OpenVM

Expand Down
72 changes: 72 additions & 0 deletions docs/vocs/docs/pages/specs/reference/rust-frontend.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# OpenVM Rust Frontend

OpenVM supports a Rust frontend via compilation to a 32-bit RISC-V target which is
then transpiled into an OpenVM executable with instructions from the RV32IM VM extension.
We implement this by **cross-compiling** for a platform which differs from the machine
performing the build. This involves the following:

- **Host**: The target and compiler toolchain used to run the program build and proving binaries.
- **Guest**: The target and compiler toolchain used to build the program to be proven.

We detail the host and guest target and toolchain as well as the guest runtime for the
OpenVM Rust frontend below.

## Host and Guest Target and Toolchain

The OpenVM Rust frontend supports the following host and guest target and toolchains:

- **Host**: We support `aarch64-apple-darwin` and `x86_64-unknown-linux-gnu` with Rust 1.86.0: `rustc 1.86.0 (05f9846f8 2025-03-31)`.
For reproducible builds, we recommend using the `x86_64-unknown-linux-gnu` platform.
- **Guest**: `riscv32im-risc0-zkvm-elf` with Rust `nightly-2025-02-14`: `rustc 1.86.0-nightly (a567209da 2025-02-13)`.

The `riscv32im-risc0-zkvm-elf` guest target incorporates special support for
zkVMs and has official support by the
[Rust toolchain](https://doc.rust-lang.org/rustc/platform-support/riscv32im-risc0-zkvm-elf.html).
We anticipate upstreaming an OpenVM-specific target to Rust in the future.

:::info
We use a nightly Rust toolchain for the guest target in order to compile the Rust standard library for this target because it is a [Tier 3](https://doc.rust-lang.org/beta/rustc/target-tier-policy.html#tier-3-target-policy) target.
:::

## Guest Runtime

The OpenVM Rust runtime supports `no_std` Rust by default, with optional `std` support available
through the `"std"` feature. This section documents the different features of the runtime.

### Memory Allocator

OpenVM supports 512MB of guest memory, with stack growing down from `STACK_TOP = 0x0020_0400`.
program loading starting at `TEXT_START = 0x0020_0800`, and heap starting right afterwards.
We support two allocators:

- A **bump** allocator which increments a heap pointer for each successive allocation without
deallocating. This is the default allocator.
- A **linked-list** allocator from the `embedded-alloc` crate which supports deallocation
at the cost of additional allocation overhead.

The linked-list allocator can be selected by enabling the `heap-embedded-alloc` feature on the
`openvm` crate.

### System Calls

OpenVM currently does not support any system calls via the RISC-V `ecall` instruction. Instead, OpenVM supports [custom RISC-V instruction set extensions](/specs/reference/riscv-custom-code) directly via VM extensions.

In particular, [support](#std-support) for the Rust `std` library is implemented via custom RISC-V instructions.

### OpenVM Intrinsics

OpenVM supports [custom RISC-V instructions](/specs/reference/riscv-custom-code#classification-of-custom-risc-v-machine-code), known as **intrinsic instructions**, within the RISC-V ELF binary. These instructions may be inserted directly from the Rust program code using the Rust [`asm!` macro](https://doc.rust-lang.org/reference/inline-assembly.html) and the [`.insn` directive](https://doc.rust-lang.org/reference/inline-assembly.html#r-asm.directives.supported-directives).

For convenience, we define two procedural macros `custom_insn_i!` and `custom_insn_r!` that provide more streamlined interfaces for calling intrinsic instructions within Rust code. These macros are defined in the `openvm-custom-insn` crate and are re-exported in the `openvm-platform` crate. They may be accessed from the `openvm` crate via `openvm::platform::custom_insn_i!` and `openvm::platform::custom_insn_r!`.

### OpenVM Kernels

OpenVM also supports insertion of [custom kernel code](/specs/reference/riscv-custom-code#classification-of-custom-risc-v-machine-code) into the RISC-V ELF. Kernel code is used as a means to statically link foreign OpenVM assembly code into the ELF without a custom linker. Custom kernel code should be inserted from Rust using the [`asm!` macro](https://doc.rust-lang.org/reference/inline-assembly.html) and the [`.insn` directive](https://doc.rust-lang.org/reference/inline-assembly.html#r-asm.directives.supported-directives). We recommend that the kernel code is generated in a separate build script and then directly included within the `asm!` macro invocation using `include_str!`.

### `std` Support

OpenVM supports compilation of guest code using the Rust `std` library when the `openvm` crate is imported with the `"std"` feature enabled. When the `"std"` feature is enabled, the `openvm` crate defines `extern "C"` functions that are compatible with the platform abstraction layer (PAL) ABI defined in the Rust standard library for the guest target. These ABI definitions are statically linked with the Rust standard library at compile time.

The PAL ABI is implemented in `openvm` using Rust and direct calls to [OpenVM intrinsics](#openvm-intrinsics) without the use of system calls.

Users should be aware of the limitations of the Rust `std` support within OpenVM, which are documented in the [book](/book/writing-apps/writing-a-program#rust-std-library-support).
4 changes: 4 additions & 0 deletions docs/vocs/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export const specsSidebar: SidebarItem[] = [
{
text: "RISC-V Transpiler",
link: "/specs/reference/transpiler"
},
{
text: "Rust Frontend",
link: "/specs/reference/rust-frontend"
}
]
}
Expand Down
Loading