System software development presents a fundamental challenge that every bare metal project must solve: bridging the gap between the processor's minimal boot state and a fully functional execution environment capable of running high-level code. When a processor first transfers control to system software - whether firmware, kernel, hypervisor, or any bare metal application - it operates in a primitive state with no stack, no memory management, and minimal initialization of the processor. This creates an immediate dependency: before any C, Rust, or other high-level language code can execute, developers must craft assembly routines to establish the required runtime environment for the software component.
The RISC-V architecture's elegant design philosophy amplifies both the opportunity and complexity of this challenge. RISC-V defines two primary base instruction set architectures (ISA) - RV32I (32-bit registers and addresses) and RV64I (64-bit registers and addresses). As articulated in the RISC-V unprivileged specification[1], the ISA represents "the software visible interface to a wide variety of implementations rather than the design of a particular hardware artifact." It also defines RISC-V Execution Environment Interface (EEI), which standardizes critical aspects of program execution: initial processor state, privilege mode behavior (Machine, Supervisor, and User modes), instruction semantics, and interrupt/exception handling. While this standardization creates opportunities for code reuse and shared expertise across RISC-V projects, the reality is that most projects end up implementing similar runtime initialization routines from scratch.
Recognizing this common need, we(Rivos) developed rv-runtime-generator, an open-source Rust-based tool that automates the generation of RISC-V runtime initialization code. Rather than forcing each project to solve the same fundamental problem repeatedly, rv-runtime-generator provides a configurable solution that adapts to diverse system software requirements.
This talk will dive into the architectural design of the rv-runtime-generator tool and provide examples demonstrating its application in the rapid development of runtime environments for RISC-V software components.