2015-07-13 16 views
7

Ich habe die folgenden einfachen C-Code:Wie kann ich C-Code kompilieren, um ein Bare-Metal-Skelett eines minimalen RISC-V-Assembly-Programms zu erhalten?

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

Als ich das kompilieren mit

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

Wenn ich den Assembler-Code sehen, möchte ich verwenden

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

Aber wenn ich erkunden der Assembly-Code Ich sehe, dass dies eine Menge Code generiert, die ich für die Unterstützung von Proxy-Kernel bin (ich bin ein Neuling für Riscv). Ich möchte jedoch nicht, dass dieser Code Unterstützung für den Proxy-Kernel bietet, da die Idee darin besteht, nur diesen einfachen C-Code in einem FPGA zu implementieren.

las ich, dass riscv drei Arten von Zusammenstellung bietet: Bare-Metal-Modus, newlib Proxy-Kernel und riscv Linux. Nach früheren Forschungen ist die Art der Kompilierung, die ich machen sollte, Bare-Metal-Modus. Dies liegt daran, dass ich eine minimale Assembly ohne Unterstützung für das Betriebssystem oder den Kernel-Proxy möchte. Baugruppenfunktionen als Systemaufruf sind nicht erforderlich.

Allerdings konnte ich noch nicht finden, da ich einen C-Code für ein Skelett eines minimalen Riscv-Assembly-Programms kompilieren kann. Wie kann ich den obigen C-Code im Bare-Metal-Modus kompilieren oder ein Skelett eines minimalen Risiko-Assembly-Codes erhalten?

Antwort

4

Der "extra" Code wird dort von gcc gesetzt und ist die Art von Zeug für jedes Programm. Der Proxy-Kernel ist so konzipiert, dass er den Mindestumfang an Unterstützung bietet, der zum Ausführen solcher Dinge erforderlich ist. Sobald Ihr Prozessor funktioniert, würde ich empfehlen, Dinge auf pk statt Bare-Metal zu laufen.

In der Zwischenzeit, wenn man sich eine einfache Montage aussehen wollen, würde ich empfehlen, die Verknüpfung Phase mit ‚-c‘ Überspringen:

riscv64-unknown-elf-gcc code.c -c -o code.o 
riscv64-unknown-elf-objdump -d code.o 

Beispiele für Code ohne pk oder Linux läuft, würde ich schauen unter riscv-tests.

8

Warnung: diese Antwort ist etwas out-of-date wie die neueste RISC-V Privilegierte Spec v1.9, die die Entfernung des tohost Steuer-/Statusregister (CSR), der ein Teil war umfasst von das nicht standardmäßige Host-Ziel-Interface (HTIF), das seitdem entfernt wurde. Die aktuelle (Stand: 2016 Sep) riscv-tests führt stattdessen einen speicherplatzierten Speicher zu einem tohost Speicherort, der in einer angebundenen Umgebung von der front-end server überwacht wird.


Wenn Sie wirklich und wirklich Notwendigkeit/wollen RISC-V-Code Bare-Metal laufen, dann sind hier die Anweisungen, dies zu tun. Sie verlieren eine Menge nützlicher Dinge, wie printf oder FP-Trap-Software-Emulation, die der Riscv-PK (Proxy-Kernel) bietet.

Erste Dinge zuerst - Spike bootet bei 0x200. Da Spike das goldene ISA-Simulatormodell ist, sollte Ihr Kern auch bei 0x200 booten.

(Husten, ab 2015 Jul 13, der "Master" -Zweig von riscv-Werkzeuge (https://github.com/riscv/riscv-tools) wird mit einer älteren pre-V1.7 Privilegierte ISA und somit bei 0x2000 startet. Dieser Beitrag wird Angenommen, Sie verwenden v1.7+, für die möglicherweise der Zweig "new_privileged_isa" von riscv-tools benötigt wird.

Also, wenn Sie Ihr Bare-Metal-Programm zerlegen, ist es besser Start bei 0x200 !!! Wenn Sie es auf dem Proxy-Kernel ausführen wollen, starten Sie es besser bei 0x10000 (und wenn Linux, ist es etwas noch größer ...).

Jetzt, wenn Sie Bare-Metal ausführen möchten, zwingen Sie sich, den Prozessor-Boot-Code zu schreiben. Jawohl. Aber lassen Sie uns darauf stoßen und so tun, als ob das nicht notwendig ist.

(Sie können auch riscv-Tests/env/p, für die „virtuelle Maschine“ Beschreibung für eine physikalisch adressierte Maschine suchen. Sie werden den Linker-Skript Sie brauchen, und einige macros.h finden einige beschreiben Initial Setup-Code oder besser noch in Riscv-Tests/Benchmarks/common.crt.S).


Anyways, bewaffnet mit dem oben (verwirrend) Wissen, lassen Sie uns, dass alle wegzuwerfen und von Grund auf selbst beginnen ...

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 

und 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 = .; 
} 

Jetzt zum kompilieren ...

riscv64-unbekannt-elf-gcc -nostdlib -nostart Dateien -Tlink.ld -o hallo hello.s

Dies kompiliert (riscv64-unknown-Elf-objdump -d hallo):

hello: file format elf64-littleriscv 

Disassembly of section .text: 

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

Und es laufen:

spike hello 

Es ist eine Sache der Schönheit.

Das Link-Skript platziert unseren Code bei 0x200. Spike beginnt bei 0x200 und schreibt dann eine # 1 in das Kontroll-/Statusregister "tohost", was Spike sagt "Stop running". Und dann drehen wir auf eine Adresse (1: j 1b), bis der Front-End-Server die Nachricht bekommen hat und uns tötet.

Es kann möglich sein, das Linker-Skript zu entfernen, wenn Sie herausfinden können, wie man den Compiler auf < _start> zu 0x200 selbst bewegen.


Für weitere Beispiele, können Sie die folgenden Repositories lesen:

Die riscv-Tests Repository hält die RISC-V ISA-Tests, die sehr minimal sind (https://github.com/riscv/riscv-tests).

Dieses Makefile hat die Compiler-Optionen: https://github.com/riscv/riscv-tests/blob/master/isa/Makefile

Und viele der „virtuelle Maschine“ Beschreibung Makros und Linker-Skripte können in riscv-Tests/env (https://github.com/riscv/riscv-test-env) gefunden werden.

Sie können sich den "einfachsten" Test unter() ansehen.

Und Sie können riscv-tests/benchmarks/common für Start-und Support-Code für den Lauf Bare-Metal.

+0

Hallo Chris, danke für deine Antwort, es war sehr fertig. Im Bare-Metal-Modus verliere ich eine Menge Zeug wie printf, aber was passiert, wenn ich arithmetische Funktionen in C wie "pow" verwenden möchte? Arithmetische Funktionen wie pow befinden sich in der Math-Bibliothek. Wenn ich es kompiliere, verwende $ riscv-unknown-elf-gcc -nostdlib -nostartfiles -T.link.ld -o code code.c -lm, nehme ich an, dass es nicht im Bare-Metal-Modell funktioniert. Ich nehme an, dass ich diese Bibliothek im Bare-Metal-Modus verlinken sollte? Oder was passiert in diesem Fall? – Adrian

+0

Angesichts seiner hohen Erfahrung in Risc-v, empfehlen Sie mir besser auf der Proxy-Kernel-Ebene zu arbeiten, wenn ich zum Beispiel Math-Bibliotheken verwende? – Adrian

+0

Ich habe keine Erfahrung in der Verknüpfung in anderen Bibliotheksfunktionen; Ich vermute, du solltest lieber ein gcc/compiler-forum fragen (es ist nicht wirklich eine RISC-V-Frage). Ich denke nicht, dass es einen Grund gibt, warum es nicht funktionieren würde. – Chris