# RISC-V Playground Willkommen in dem RISC-V Playground! ## Installation *Dieser Schritt ist in der gelieferten VM bereits abgeschlossen* 1. Um den RISC-V Emulator zu installieren brauchst du Python 3 und den Python Package Manger pip. Unter Linux ist das in dem Paketmanager deiner Distribution enthalten. 2. Installiere den Emulator als pip Paket (das Paket heißt `riscemu`): `pip install riscemu` 3. Teste deine Installation mit `python3 -m riscemu --version`, es sollte mindestens Version `2.0.3` installiert sein. ## RISC-V Code Ausführen *Das folgende Beispiel findet auf der Konsole statt, der RISC-V Emulator hat nur ein Konsoleninterface. In Ubuntu kann mit hilfe des Kontextmenüs (Rechtsklick) im Dateibrowser die Eintrag "Im Terminal öffnen" ein Terminal öffnen, in dem bereits der Ordner geöffnet ist.* Betrachten wir das beispiel: `hello-world.asm` ``` # hello-world.asm # print "hello world" to stdout and exit .data text: .asci "Hello World\n" .text li a0, 1 la a1, text li a2, 12 li a7, 64 ecall li a0, 0 li a7, 93 ecall ``` Das Programm kann auf der konsole mit dem dem Befehl `python3 -m riscemu hello-world.asm` ausgeführt werden. Dafür solltest du in der Konsole in dem gleichen Ordner wie dein assembly program sein. Es sollte das folgende Output in deiner Konsole erscheinen: ``` > python3 -m riscemu hello-world.asm Hello World ``` Der emulator kann mit verschiedenen Parametern gestartet werden, z.B. kann mit `-v` die `verbosity` (die menge an Informationen die ausgegeben werden) erhöht werden. Das wiederholen der "v"s erhöht das level weiter. So wird z.B. mit dem ersten `-v` bei jedem Sprung das Sprungziel ausgegeben sowie mehr informationen über den Start und Stopp. Ab `-vv` wird jeder ausgeführte assembly Befehl ausgegeben: ``` [CPU] Created stack of size 524288 at 0x130 [CPU] Started running from hello-world.asm:.text at text (0x100) + 0x10 Program(name=hello-world.asm,sections=set(),base=['.data', '.text']) Running 0x00000110: li a0, 1 Running 0x00000114: la a1, text Running 0x00000118: li a2, 12 Running 0x0000011C: li a7, 64 Running 0x00000120: ecall Hello World Running 0x00000124: li a0, 0 Running 0x00000128: li a7, 93 Running 0x0000012C: ecall [CPU] Program exited with code 0 ``` ## Debugging Der RISC-V Standard hat einen befehl reserviert der als sogenannter "Breakpoint" agiert. Wenn der Emulator diesen befehl erkennt, wird ein interaktiver Debugger gestartet. Lass uns nun hinter den ersten `ecall` Befehl in `hello-world.asm` einen Breakpoint-Befehl einfügen: ``` # ... .text li a0, 1 la a1, text li a2, 12 li a7, 64 ecall ebreak # Breakpoint um den Debugger zu starten li a0, 0 li a7, 93 ecall ``` Wenn das Programm nun ausgeführt wird, erscheint das folgende Output generiert: ``` Hello World Debug instruction encountered at 0x00000127 [CPU] Debugger launch requested! >>> ```` Dies ist der interaktive Debugger. Hier kann der Zustand der Register, des CPUs und des Arbeitsspeichers betrachtet werden. Eine übersicht der wichtigsten Funktionen sind in der debugging.md Datei zu finden. ## Installation der RISC-V Gnu Toolchain *Auch dieser Schritt ist in der VM schon erledigt.* Für die Installatio unter Linux (Ubuntu) ist ein installationsskript beigelegt, welches die RISC-V toolchain für die Nutzung im Rahmen der Vorlesung konfiguriert und kompiliert. Ich bin mir nicht sicher ob die toolchain unter Windows kompilierbar ist, nehmt dafür am besten das [WSL](https://docs.microsoft.com/en-us/windows/wsl/install) Falls das Skript für eure Platform nicht funktioniert, hier noch ein paar tips: - Ihr braucht ca 8 Gigabyte Festplattenplatz um RISC-V GCC zu kompilieren. (Ein teil kann nach der Installation gelöscht werden). - In der [GitHub Readme](https://github.com/riscv-collab/riscv-gnu-toolchain#readme) findet ihr die genauen pakete, die ihr auf eurer Distro installierne müsst. - Klont das Repository mit `git clone --depth 1 https://github.com/riscv-collab/riscv-gnu-toolchain.git` um nicht die ganze git history mit herunter zu laden. - Konfiguriert die Installation mit dem folgenden Befehl (dafür müsst ihr in die geklonte repo rein `cd`'en): `./configure --prefix=$(pwd)/../toolchain/ --with-arch=rv32ima --disable-linux --disable-gdb --disable-multilib`. Der Zielordner muss unbedingt vorher angelegt werden! Also `mkdir $(pwd)/../toolchain/` (Legt den ordner `toolchain` im Überordner der Repo an). - Baut den compiler mit allen verfügbaren threads: `make -j `. - Nach der installation sollte der `toolchain/bin` Ordner zu dem `$PATH` hinzugefügt werden, hierfür gibt es mehrere Möglichkeiten. Hier ein tutorial zur `$PATH` vairable: https://www.howtogeek.com/658904/how-to-add-a-directory-to-your-path-in-linux/ Nach der installation sollte es möglich sein C und RISC-V Assembly in RISC-V Objektdateien und executables zu kompilieren und den bytecode aus zu geben: ``` # "riscv32-unknown-elf" ist das präfix, und "as" der befehl für den Assembler: > riscv32-unknown-elf-as hello-world.asm -o hello-world.out # gleiches präfix, hier benutzen wir "objdump" um den compilierten Inhalt zu decodieren: > riscv32-unknown-elf-objdump -SF hello-world.out hello-world.out: file format elf32-littleriscv Disassembly of section .text: 00000000 <.text> (File Offset: 0x34): 0: 00100513 li a0,1 4: 00000597 auipc a1,0x0 8: 00058593 mv a1,a1 c: 00c00613 li a2,12 10: 04000893 li a7,64 14: 00000073 ecall 18: 00000513 li a0,0 1c: 05d00893 li a7,93 20: 00000073 ecall ```