Syntacore RISC-V Minimal First Stage Bootloader
Miniboot is a first-stage bootloader developed by Syntacore for its RISC-V processor cores. Its primary purpose is to execute prior to the RISC-V Open Source Supervisor Binary Interface (OpenSBI) and prepare the system for subsequent boot stages.
A typical bootflow with Miniboot is:
Miniboot -> OpenSBI -> U-Boot -> Linux
Miniboot resides in cluster SRAM. When the cores exit reset, execution begins from this location. During early initialization, Miniboot performs essential cluster configuration, including:
- Cache initialization
- Memory Routing Table (MRT) configuration
- Partial Physical Memory Protection (PMP) setup (e.g., configuring DRAM as cacheable)
Once initialization is complete, Miniboot transfers control to the next boot stage. For OpenSBI,
it passes the device tree address via register a1, then jumps to the OpenSBI entry point.
Although Miniboot was originally designed to serve as an early-stage loader for OpenSBI, it is not limited to that use case. It can launch any baremetal image, if the next stage entry address is specified appropriately.
Miniboot is built on top of SCR-HAL platforms. It reuses the platform-specific configuration and initialization routines defined within SCR-HAL, ensuring consistency across supported cores.
Syntacore Development Toolkit (SC-DT) is required to build Miniboot. It can be obtained from the following link: syntacore development tools. Download the archive (.tar.gz for Linux, .zip for Windows) for your platform. The SC-DT package includes pre-build RISC-V GCC toolchain, SCR-QEMU, CMake toolchain files and SCR-HAL. These components are mandatory to build Miniboot and perform test execution in qemu.
⚠️ Current Miniboot version is compatible with sc-dt-2025.12.
The instructions below are intended for Ubuntu systems.
Set path for toolkit installation directory
$ export SC_DT_PATH=/path/to/sc-dt/installation/directorySC-DT comes with a pre-configured env.sh script that you can use to set all required environment
variables:
$ source $SC_DT_PATH/env.shAlternatively, you can specify variables manually:
$ export SC_HAL_PATH=$SC_DT_PATH/workspace/scr-hal
$ export SC_GCC_PATH=$SC_DT_PATH/riscv-gcc
$ export SC_CMAKE_TOOLCHAINS=$SC_DT_PATH/workspace/cmake-toolchainsThe most basic build command is shown below:
$ MINIBOOT_PATH=/path/to/miniboot
$ BUILD_DIR=build
$ rm -rf $BUILD_DIR
$ cmake -S $MINIBOOT_PATH \
-B $BUILD_DIR \
-DTOOLCHAIN_FILE=$SC_CMAKE_TOOLCHAINS/riscv64-elf-gcc.cmake \
-DPLATFORM=rv64_pmp_l3 && \
cmake --build $BUILD_DIRWhere
-DTOOLCHAIN_FILE
Specifies cmake toolchain file. Onlyriscv64-elf-gcc.cmakeis supported.-DPLATFORM
Defines the target Miniboot platform to build. Refer to Platforms section to gain more information.
The Miniboot build can be customized using additional build options. For further details, refer to Build options section.
Miniboot uses an internal naming convention for certain platform builds. Because bootloader initializes only a limited subset of cluster-level peripherals, a single Miniboot binary can support multiple core types.
For example:
rv64_mpu_l2- Indicates a build targeting the RV64 architecture, with an L2 last-level cache and an MPU-based memory protection mechanism.
Miniboot builds are based on SCR-HAL platforms. The common platform configuration is derived from a selected SCR-HAL platform. SCR-HAL platforms that cannot be grouped under the common platform are built separately, such as scr6. The compliance table below summarizes the relationship between Miniboot builds and their corresponding SCR-HAL platforms.
| Miniboot | SCR-HAL | Cores | Arch | Last Level Cache | Memory Protection |
|---|---|---|---|---|---|
| rv64_pmp_l3 | scr9_l3 | SCR9 | RV64 | L3 | PMP |
| rv64_pmp_l2 | scr9_l2 | SCR9, SCR7 | RV64 | L2 | PMP |
| scr6 | scr6 | SCR6 | RV64 | L2 | PMP |
| rv64_mpu_l2 | scr5_rv64 | SCR5, SCR4, SCR3 | RV64 | L2 | MPU |
| scr5_rv32 | scr5_rv32 | SCR5 | RV32 | L2 | MPU |
| rv32_mpu_l1 | scr5_rv32 | SCR4, SCR3 | RV32 | L1 | MPU |
| scr1 | scr1 | SCR1 | RV32 | - | - |
Miniboot behavior and feature set can be further configured at compile time. The table below lists the supported build options along with their descriptions, default values, and usage examples.
| Option | Description | Default value | Usage |
|---|---|---|---|
| INSTANT_BOOT | Skips the autoboot countdown and CLI. Miniboot immediately transfers control to the next boot stage. | OFF |
-DINSTANT_BOOT=ON |
| CORES_SYNC | Enables cores synchronization at a defined execution point (i.e., all cores must reach the same location in the code). | ON |
-DCORES_SYNC=OFF |
| CORES_SYNC_TIMEOUT | Defines the core synchronization timeout (in milliseconds). | 100 |
-DCORES_SYNC_TIMEOUT=<timeout_ms> |
| JUMP_NEXT_STAGE | Skips some de-initialization routine before transferring control to the next boot stage. Typically used when OpenSBI is not involved. | OFF (always enabled for scr1, rv32_mpu_l1 and scr6) |
-DJUMP_NEXT_STAGE=ON |
| GEN_MEM_FILES | Generate .mem files in build directory. | OFF |
-DGEN_MEM_FILES=ON |
| NEXT_BOOT_STAGE_ADDR | Specifies the entry address of the next boot stage. | DRAM start address | -DNEXT_BOOT_STAGE_ADDR=<address> |
| FDT_ADDR_OFFSET | Offset of the device tree from NEXT_BOOT_STAGE_ADDR. Used to calculate the FDT address. | 0x2200000 |
-DFDT_ADDR_OFFSET=<offset> |
| AUTOBOOT_TIMEOUT | Sets the autoboot countdown duration (in seconds). | 3 |
-DAUTOBOOT_TIMEOUT=<seconds> |
| XSPI_FLASH_BASE | Base address of the Xilinx SPI Flash. Used together with XSPI_FLASH_CS. | Not set | -DXSPI_FLASH_BASE=<xspi_base> |
| XSPI_FLASH_CS | Chip select line for Xilinx SPI Flash. When both XSPI_FLASH_BASE and XSPI_FLASH_CS are defined, SPI Flash support is enabled. | Not set | -DXSPI_FLASH_CS=<cs_line> |
| CLI_PROMPT | Customizes the Miniboot CLI prompt string. | > |
-DCLI_PROMPT=\"prompt\" |
In addition to the options listed above, SCR-HAL specific compile time options may also be provided. Refer to the SCR-HAL documentation for details.
Miniboot functionality for a selected platform can be verified by running it in qemu.
If you have sourced the SC-DT env.sh script, the environment variables SC_QEMU_SYSTEM64 and
SC_QEMU_SYSTEM32 are already exported. Otherwise, you must define the QEMU binaries manually:
$ SC_QEMU_SYSTEM64=$SC_DT_PATH/tools/bin/qemu-system-riscv64
$ SC_QEMU_SYSTEM32=$SC_DT_PATH/tools/bin/qemu-system-riscv32Example: Running Miniboot on scr7_l2 qemu machine:
$ MINIBOOT_BUILD_DIR=/path/to/miniboot/build
$ $SC_QEMU_SYSTEM64 \
-M scr7_l2,close-at-exit=true \
-smp 8 \
-nographic \
-bios $MINIBOOT_BUILD_DIR/miniboot.elfMiniboot prints basic system information during execution. A typical output looks like this:
Miniboot v0.0.1-4ebb918 SMP
Copyright (C) 2025 Syntacore, Syntacore Ltd. All rights reserved.
ISA: RV64IMAFDCBKV [800000000034152f]
IMPID: 40
ARCHID: 8000000013007107
VENDORID: 6bb
BUILDID: 22041500
Platform: rv64_pmp_l2, running on SCR7
Clocks: sys 65.000 MHz, cluster 65.000 MHz, rtc 65.000 MHz, uart 65.000 MHz
Hart 0: master, 65.000 MHz
Hart 1: active, 65.000 MHz
Hart 2: active, 65.000 MHz
Hart 3: active, 65.000 MHz
Hart 4: active, 65.000 MHz
Hart 5: active, 65.000 MHz
Hart 6: active, 65.000 MHz
Hart 7: active, 65.000 MHz
SMP: Found 8 active hart(s)
L1i: [0843] 32K, 8-ways, 16-bytes line, enabled
L1d: [2843] 32K, 8-ways, 16-bytes line, enabled
L2: [24112601 7001e863] 256K, 8-ways, 64-bytes line, shared (8 cores), enabled
Next Address: 0
Next Arg1: 2200000
Next mode: M-mode
Press space key to stop autoboot
Remaining time: 3
By default, the autoboot feature is enabled. You have 3 (usually) seconds to press the space key to stop it. If autoboot is not interrupted, Miniboot automatically transfers control to the next boot stage. If you press the space key in time, the Miniboot prompt is displayed, allowing interaction. At the prompt, Miniboot supports a predefined set of commands that can be used. More in CLI section.
When the Miniboot prompt appears, you can inspect the list of supported commands by typing help
or its shorthand h. A detailed message will be displayed showing each command, its shorthand, and
a short description:
> h
Available commands:
help (h) - Display help message
boot (b) - Boot to next stage to boot Linux
jump (j) - Jump directly to the next stage for noMMU Linux or baremetal
sysinfo (i) - Show system information
memtest (t) - Memory test
timertest (tt) - Test mtimer synchronization
memdump (d) - Show memory dump
memmodify (m) - Modify memory
xspi (xs) - Operations on spi flash
xmodem (xm) - XMODEM file receive
Type 'help <command>' for more details on specific command
To see detailed information about a particular command, type:
> h memdump
memdump (d) - Show memory dump
Usage:
memdump [addr] [len] [chunk] [cols] - Show memory dump with address <addr>, <len> bytes size, <chunk> bytes read (1,2,4,8), <cols> octets per line (>0)
After you are done working with the CLI, execute either the boot or jump command to transition
all cores to the next boot stage. While executing these commands, you may pass optional arguments
such as the next stage address and/or device tree address. Miniboot will display configured values:
> boot
Next Address: 0
Next Arg1: 2200000
Next mode: M-mode