17

次の単純な C コードがあります。

   void main(){
    int A = 333;
    int B=244;
    int sum;
    sum = A + B;  
}

これをコンパイルすると

$riscv64-unknown-elf-gcc code.c -o code.o

私が使用するアセンブリコードを見たい場合

$riscv64-unknown-elf-objdump -d code.o 

しかし、アセンブリ コードを調べると、プロキシ カーネルのサポート用であると思われる多くのコードが生成されることがわかります (私は riscv の初心者です)。ただし、FPGA 内にこの単純な C コードのみを実装することを目的としているため、このコードがプロキシ カーネルをサポートすることは望ましくありません。

riscv には、ベアメタル モード、newlib プロキシ カーネル、および riscv Linux の 3 種類のコンパイルが用意されていると読みました。以前の調査によると、私が行うべきコンパイルの種類はベア メタル モードです。これは、オペレーティング システムまたはカーネル プロキシをサポートしない最小限のアセンブリが必要なためです。システムコールとしてのアセンブリ関数は必要ありません。

ただし、最小限のriscvアセンブリプログラムのスケルトンを取得するためにCコードをコンパイルできるため、まだ見つけることができていません。上記の C コードをベア メタル モードでコンパイルしたり、最小限の riscv アセンブリ コードのスケルトンを取得するにはどうすればよいですか?

4

3 に答える 3

18

警告:この回答は、最新の RISC-V Privileged Spec v1.9 の時点でやや古くなっています。これにはtohost、非標準のホスト ターゲットの一部であったコントロール/ステータス レジスタ (CSR)の削除が含まれています。その後削除されたインターフェイス (HTIF)。現在 (2016 年 9 月現在)riscv-testsは代わりにメモリ ロケーションへのメモリ マップ ストアを実行します。tohostテザリング環境では、front-end server.


本当にRISC-V コードをベアメタルで実行する必要がある、または実行したい場合は、次の手順に従っください。riscv-pk (プロキシ カーネル) が提供する printf や FP-trap ソフトウェア エミュレーションなど、多くの便利なものが失われます。

まず最初に - Spike は 0x200 で起動します。Spike はゴールデン ISA シミュレータ モデルであるため、コアも 0x200 で起動する必要があります。

(、2015 年 7 月 13 日現在、riscv-tools の「マスター」ブランチ ( https://github.com/riscv/riscv-tools ) は古い v1.7 より前の特権 ISA を使用しているため、0x2000 から始まります。 . この投稿では、v1.7+ を使用していることを前提としていますが、riscv-tools の「new_privileged_isa」ブランチを使用する必要がある場合があります)。

したがって、ベアメタル プログラムを逆アセンブルするときは、0x200 から開始することをお勧めします!!! プロキシ カーネルの上で実行したい場合は、0x10000 から開始することをお勧めします (Linux の場合は、さらに大きなものになります…)。

ベア メタルを実行したい場合は、プロセッサのブート コードを作成する必要があります。うん。しかし、それをパントして、それが必要ないふりをしましょう.

(物理的にアドレス指定されたマシンの「仮想マシン」の説明については、riscv-tests/env/p を調べることもできます。必要なリンカ スクリプトと、いくつかの初期セットアップ コードを説明するためのいくつかの macros.h が見つかります。まだ、riscv-tests/benchmarks/common.crt.S にあります)。


とにかく、上記の(紛らわしい)知識で武装して、それをすべて捨てて、ゼロから始めましょう...

hello.s:
 .align 6
 .globl _start
 _start:
 # screw boot code, we're going minimalist
 # mtohost is the CSR in machine mode
 csrw mtohost, 1;
 1:
 j 1b

および link.ld:

 OUTPUT_ARCH( "riscv" )
 ENTRY( _start )
 SECTIONS
 {
 /* text: test code section */
 . = 0x200;
 .text :
 {
 *(.text)
 }
 /* data: Initialized data segment */
 .data :
 {
 *(.data)
 }
 /* End of uninitalized data segement */
 _end = .;
 }

これをコンパイルするには…</p>

riscv64-unknown-elf-gcc -nostdlib -nostartfiles -Tlink.ld -o こんにちは hello.s

これは (riscv64-unknown-elf-objdump -d hello) にコンパイルされます。

 hello: file format elf64-littleriscv

 Disassembly of section .text:

 0000000000000200 <_start>:
 200: 7810d073 csrwi tohost,1
 204: 0000006f j 204 <_start+0x4>

そしてそれを実行するには:

spike hello

それは美しいものです。

リンク スクリプトはコードを 0x200 に配置します。Spike は 0x200 で開始し、コントロール/ステータス レジスタ「tohost」に #1 を書き込み、Spike に「実行を停止する」ように指示します。そして、フロントエンド サーバーがメッセージを受信して​​強制終了するまで、アドレス (1: j 1b) をスピンします。

<_start> を独自に 0x200 に移動するようにコンパイラに指示する方法を理解できれば、リンカー スクリプトを破棄できる可能性があります。


他の例については、次のリポジトリを参照できます。

riscv-tests リポジトリには、最小限の RISC-V ISA テストが含まれています ( https://github.com/riscv/riscv-tests )。

この Makefile にはコンパイラ オプションがあります: https://github.com/riscv/riscv-tests/blob/master/isa/Makefile

また、「仮想マシン」記述マクロとリンカー スクリプトの多くは、riscv-tests/env ( https://github.com/riscv/riscv-test-env ) にあります。

( ) で「最も単純な」テストを見ることができますriscv-tests/isa/rv64ui-p-simple.dump

riscv-tests/benchmarks/commonまた、ベアメタルを実行するための起動コードとサポート コードを確認できます。

于 2015-07-13T21:32:57.507 に答える