
Rustで書かれたRISC-Vエミュレータ。ARM64/x86_64上でJITを使ってLinuxを起動し、Sv39仮想メモリに対応。
Rustで書かれたRISC-Vエミュレータです。Linuxを起動します。
このマシンは、M/S/U特権レベルとSv39仮想メモリを備えたRV64IMAFDCを実装しています。
ARM64およびx86_64ホスト上でJITを実行し、必要に応じてインタプリタにフォールバックします。
ペリフェラルはUART 16550、CLINT、PLIC、SBI 1.0です。外部依存関係は1つ: zstd です。
最速のエミュレータではありません。インタプリタモードでは、QEMUの約3倍遅く動作します。 JITモードでは、約29倍遅くなります。コードブロックチェーンはまだ実装されていません。 それが役立つでしょう。何が得られるかを知っておくべきなので、率直に述べています。
優れている点: 操作が簡単で、マシン制御用のHTTP APIを公開しており、 カーネルなしでベアメタルELFを実行でき、完全なマシン状態の保存と復元が可能です。 これらはシステム開発やテストに役立つ機能です。
cargo build --release
バイナリは target/release/emuko です。エイリアスを作成してください。
alias emuko=target/release/emuko
emuko dow
Debian RISC-V netbootカーネルとinitrdを ~/.emuko/ にダウンロードします。
SHA256が検証されます。独自のカーネルは必要ありません。
emuko start
エミュレータはデーモンとして実行されます。コンソールに接続されます。 カーネルが起動するのを確認できます。シェルが表示されます。
| キー | 効果 |
|---|---|
| Ctrl+] | 切り離し(デーモンは継続) |
| Ctrl+C | ゲスト内で割り込み |
| Ctrl+D | ゲスト内でEOF |
emuko start # コンソールに再接続
emuko dump # CPU状態を表示
emuko stop # 実行を一時停止
emuko con # 実行を再開
emuko step 1000 # N命令をシングルステップ実行
emuko snap # スナップショットを取得
emuko kill # シャットダウン
デーモンは http://127.0.0.1:7788/v1/api/ でリッスンし、
WebSocketコンソール接続を ws://127.0.0.1:7788/v1/ws/uart で受け付けます。
どちらもスクリプトから使用できます。
オペレーティングシステムが必要ない場合もあります。マシンとバイナリだけあれば十分です。
emuko run ./my_program.elf
デーモンはマシンをリセットし、ELFセグメントを物理アドレスにロードして実行を開始します。 出力はUARTコンソールを介して到着します。デーモンがすでに実行されている必要があります。
ベアメタルからコンソールに書き込むには: 0x1000_0000 にバイトを格納します。
examples/ ディレクトリには、この方法で実行されるプログラムが含まれています。
| 例 | 説明 |
|---|---|
bare_printf | 1000万回のイテレーションごとにメッセージを表示します。libcなし。直接UART書き込み。 |
ビルドにはRISC-Vクロスコンパイラが必要です。
macOSの場合: brew install riscv64-elf-gcc。
Linuxの場合: apt install gcc-riscv64-linux-gnu。
emuko start
cd examples/bare_printf
make run
マシンの状態(レジスタ、メモリ、すべて)を保存および復元できます。
emuko snap # 今スナップショットを取得
emuko snap 5000000 # 500万ステップごとに自動スナップショット
emuko snap stop # 自動スナップショットを停止
emuko ls # スナップショット一覧
emuko restore <snapshot> # 復元
仮想マシンは、QEMU RISC-V virt プラットフォームと互換性のある固定MMIOレイアウトを使用します。
デフォルト設定(load_addr=0x80200000、1 GiB RAM)の場合:
0x8000_0000 ── RAMベース
(ギャップ — ベアメタルプログラムで使用可能)
0x8020_0000 ── カーネルイメージ
│ .text / .rodata / .data / .bss
└─ カーネル終端
(空き)
── initrd
── DTB
── EFI領域 (128 KiB、PE/UEFIカーネルのみ)
0xBFFF_FFFF ── RAM終端
DTB、initrd、EFIはRAMの上部から下方に配置されます。エミュレータは起動時にカーネルとの重複をチェックし、 RAMが小さすぎる場合は明確なエラーで停止します。
ELFの PT_LOAD セグメントは、その p_vaddr アドレスに配置されます。
bare_printf は 0x8000_0000 でリンクします:
0x8000_0000 ── .text
── .rodata
── .data
── .bss (start.Sによってゼロ初期化)
── スタック (BSSの上の16 KiB)
カーネルなし。initrdなし。DTBなし。レジスタは sp を除いてゼロから開始します。
sp はエミュレータによって ram_base + 0x100000 に設定され、その後 start.S が引き継ぎます。
オプションはコマンドラインで渡すか、環境変数として設定するか、emuko.yml に記述できます。
一般的に使用されるRISC-Vエミュレータとの直接比較。
✅ = サポートされ文書化されている。— = 組み込まれていない。
出典: QEMU virt · Spike · Renode
Apache 2.0。 LICENSE を参照。
| 領域 | ベース | サイズ | 備考 |
|---|
| CLINT | 0x0200_0000 | 64 KiB | タイマーおよびソフトウェアIRQ |
| PLIC | 0x0C00_0000 | 4 MiB | 32個の割り込みソース |
| UART | 0x1000_0000 | 256 B | NS16550A、IRQ 10 |
| RAM | 0x8000_0000 | 1 GiB | 設定可能 |
| オプション | 環境変数 | デフォルト | 備考 |
|---|
--ram-size | RAM_SIZE | 1 GB | RAMサイズ(バイト) |
--backend | EMUKO_BACKEND | adaptive | adaptive、arm64_jit、amd64_jit、arm64、x86_64 |
--bootargs | BOOTARGS | シリアルコンソール | カーネルコマンドライン |
| 機能 | emuko | QEMU | Spike | Renode |
|---|
| JIT / 動的変換 | ✅ | ✅ | — | — |
| スナップショット保存と復元 | ✅ | ✅ | — | ✅ |
| 定期的な自動スナップショット | ✅ | — | — | ✅ |
| マシン制御用HTTP API | ✅ | — | — | — |
| WebSocket UARTコンソール | ✅ | — | — | — |
| スクリプト可能なUARTホストブリッジ | ✅ | — | — | ✅ |
| ベアメタルELFアップロード(OSなし) | ✅ | — | — | — |
| ワンコマンドカーネルダウンロード + SHA256 | ✅ | — | — | — |
| JIT対インタプリタ差分チェッカー | ✅ | — | — | — |
| GDBデバッグ | — | ✅ | ✅ | ✅ |
| 大規模デバイスエコシステム(PCIe、virtio) | — | ✅ | — | — |
| マルチノードシミュレーション | — | — | — | ✅ |
| 広範なISAカバレッジ(RVV、暗号など) | — | — | ✅ | — |