Memory Map

? RISC-V メモリマップの基本原則(仕様で定義されている点)

リセットベクタ(初期PC)の位置は仕様で決まる

RISC-V CPU は 起動時の PC(Reset Vector) を固定のアドレスから開始する。

▼ 典型例

モード 仕様上の既定 or 慣習
Machine モード 0x0000_1000 がよく使用される
M-mode + SBI/プロ向け SoC 0x8000_0000 が主流(Linux系)

PicoRV32 の場合は 実装側が任意(FPGA SoC では 0x0000_0000 に置くことが多い)。


メモリ空間は “フラットな32bitアドレス空間”

RISC-V では MMIO(Memory Mapped I/O)含めすべてが 1 つのアドレス空間に入ります。

0x0000_0000〜0xFFFF_FFFF の 4GB

OS がない小規模 SoC なら 4GB 全体を自由に割り当て可能。


RISC-V 仕様に最低限決まっている予約領域

RISC-V privileged spec では、以下が予約領域として扱われます:

アドレス範囲 意味
0x0000_0000 – 0x0000_0FFF M-mode トラップベクタ / 実装依存
0x0200_0000 – 0x0200_FFFF CLINT(タイマー・ソフト割り込み)
0x0C00_0000 – 0x0C00_FFFF PLIC(外部割り込みコントローラ)

Linux や QEMU-compatible SoC では必ずこの配置になります。


? では、小規模 FPGA SoC(PicoRV32)の場合は?

PicoRV32 は 完全に自由にメモリマップを設計してよい という風になっています。

多くの教育用または FPGA SoC では次のように構成します:

0x0000_0000 〜 0x0000_FFFF RAM(命令+データ)
0x0200_0000 〜 0x0200_FFFF CLINT(必要なら)
0x0300_0000 〜 0x0300_FFFF LED / GPIO
0x0300_1000 〜 0x0300_1FFF PWM
0x0300_2000 〜 0x0300_2FFF UART

あなたが先ほど使っていたメモリマップ:

0x0300_0000 LED
0x0300_1000 PWM

も RISC-V ルールに完全に沿っており、
QEMU / SiFive / Kendryte K210 などと互換性のある構成です。


? Linux 対応 RISC-V SoC の標準的なメモリマップ(HiFive Unmatched など)

実際の RISC-V 公式ボードでは次のような構成が一般的:

0x0000_0000 Boot ROM
0x0200_0000 CLINT(Timer / Software IRQ)
0x0C00_0000 PLIC
0x1000_0000 UART0
0x1001_0000 SPI
0x8000_0000 DRAM(Linux カーネル)

これは “RISC-V Platform Specification” にも適合している標準パターン。


? まとめ:RISC-V メモリマップはこう理解すれば OK

  1. 仕様上、最低限の予約エリア(CLINT・PLIC)がある

  2. SoC 開発者はその他の領域を自由に割り当ててよい

  3. 小規模 FPGA SoC(PicoRV32など)はほぼ完全に自由

  4. Linux向けSoCは QEMU 互換の固定配置を使う

  5. メモリマップの設計=SoC 開発の中心作業