Build for FE310-G002 SoC
Now, its time to build for a specific RISC-V target. What does this mean? There can be many RISC-V target variants, though the RISC-V assembly code remains the same, the target might be 32-bit/64-bit with support for different ISA (Instruction Set Architecture) extensions (ex: RV32IMAC, RV32IMA etc) and with different memory size (both ON-Chip & OFF-Chip) & with different IO support.
As mentioned in the previous edition, HiFive1 RevB board with FE310-G002 SoC is the only hardware in my hands. So, lets build for it.
Create linker for FE310-G002
Most common memory partitions are:
ROM - Read Only Memory
RAM - Random Access Memory
Peripheral Registers
External Bus Interface
System Control
Reserved
Remember the actual usable memory might differ from the memory map mentioned in the SoC data sheet.
For example, the Off-Chip Non Volatile Memory(NVM) is 512 Mebibytes(512 MiB, 1MiB = 2^ 20 bytes) in the FE310-G002 data sheet, but the actual usable memory on this SoC with Hifive1 RevB board is just 16 mebibytes as only 16MiB of memory is connected to the external bus.
Here is the simplified usable memory range & map for FE310-G002.
Memory | Start Address | Length | Size |
|---|---|---|---|
On Chip RAM | 0x80000000 | 0x4000 | 16 KiB |
Off Chip NVM/Flash | 0x20000000 | 0x1000000 | 16 MiB |
This is enough now to link our code either to RAM or FLASH to load and execute from RAM or FLASH. Writing a linker from scratch is a different topic and don’t want to deviate. Here is the linker I wrote and lets call it hifive1-revb-ram.lscript . Please ask your questions about the linker in the comments if any.
Feed fe310-g002 linker to cargo
So far the cargo workspace is not provided with any linker file. Now, its time to feed the linker to cargo so that the binary is linked with the linker hifive1-revb-ram.lscript. This can be achieved with link-args rustflags as below in .cargo/config file.
bootstrap-ws $cat .cargo/config
[build]
target = "riscv32imac-unknown-none-elf"
rustflags = [
"-C", "link-dead-code",
"-C", "link-args=-Thifive1-revb-ram.lscript"
]
With the linker for fe310, cargo build should link symbols to the RAM memory section starting from 0×8000_0000 in the linker.
bootstrap-ws $riscv64-unknown-elf-objdump -d target/riscv32imac-unknown-none-elf/debug/execs
target/riscv32imac-unknown-none-elf/debug/execs: file format elf32-littleriscv
Disassembly of section .text:
80000000 <rust_begin_unwind>:
80000000: 1141 addi sp,sp,-16
80000002: c62a sw a0,12(sp)
80000004: a009 j 80000006 <rust_begin_unwind+0x6>
80000006: a001 j 80000006 <rust_begin_unwind+0x6>
80000008 <_start>:
80000008: 8082 ret
If no particular path is set for linker, cargo expects linker in cargo workspace root directory.
bootstrap-ws $tree
.
├── Cargo.lock
├── Cargo.toml
├── execs
│ ├── Cargo.toml
│ └── src
│ └── main.rs
├── hifive1-revb-ram.lscript
└── libs
├── Cargo.toml
└── src
└── lib.rs