? 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
-
仕様上、最低限の予約エリア(CLINT・PLIC)がある
-
SoC 開発者はその他の領域を自由に割り当ててよい
-
小規模 FPGA SoC(PicoRV32など)はほぼ完全に自由
-
Linux向けSoCは QEMU 互換の固定配置を使う
-
メモリマップの設計=SoC 開発の中心作業