--- tags: computer-arch --- # Lab2: RISC-V `RV32I[MACF]` emulator with ELF support ## [rv32emu](https://github.com/sysprog21/rv32emu) * An instruction set architecture (ISA) emulator implementing the 32 bit [RISC-V processor model](https://riscv.org/technical/specifications/). * Support RISC-V extensions * RV32M: Standard Extension for Integer Multiplication and Division * RV32A: Standard Extension for Atomic Instructions * RV32C: Standard Extension for Compressed Instructions (RV32C.F excluded) * RV32F: Standard Extension for Single-Precision Floating Point Instructions * Support GDB Remote Debugging * Experimental graphical system support. See [Demos](https://github.com/sysprog21/rv32emu/blob/master/docs/demo.md). * Developed at NCKU * [note1](https://hackmd.io/@lambert-wu/rv32emu), [slides](https://docs.google.com/presentation/d/1SaLn1E_-jlHyNwIGQXJOx2aDn3uED8js07M-Egas7KM/edit), [note2](https://hackmd.io/@Risheng/rv32emu) * About 5K line of code. ## Sample Usage on Ubuntu Linux :::warning At present, we only verify on Ubuntu GNU/Linux. Please install Ubuntu Linux 20.04-LTS (or later) into your machine. It is fine with virtualization environments such as [VirtualBox](https://www.virtualbox.org/). ::: 1. Prepare GNU Toolchain for RISC-V. See [The xPack GNU RISC-V Embedded GCC](https://xpack.github.io/riscv-none-elf-gcc/) ```shell $ cd /tmp $ wget https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz $ tar zxvf xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz $ cp -af xpack-riscv-none-elf-gcc-13.2.0-2 $HOME/riscv-none-elf-gcc ``` 2. Configure `$PATH` ```shell $ cd $HOME/riscv-none-elf-gcc $ echo "export PATH=`pwd`/bin:$PATH" > setenv ``` Once step (1) and (2) are complete, you can simply update `$PATH` environment variable via: ```shell $ cd $HOME $ source riscv-none-elf-gcc/setenv ``` Check `$PATH` at the first time: ```shell $ riscv-none-elf-gcc -v ``` You shall be able to see the following messages: ``` gcc version 13.2.0 (xPack GNU RISC-V Embedded GCC x86_64) ``` 3. rv32emu relies on some third-party packages to be fully usable and to provide you full access to all of its features. Your target system must have a functional SDL2 library. * macOS: `$ brew install sdl2 sdl2_mixer` * Ubuntu Linux / Debian: `$ sudo apt install libsdl2-dev libsdl2-mixer-dev` 4. Fetch [rv32emu](https://github.com/sysprog21/rv32emu) and build from source ```shell $ git clone https://github.com/sysprog21/rv32emu $ cd rv32emu $ make ``` 5. Validate [rv32emu](https://github.com/sysprog21/rv32emu) ```shell $ make check ``` You shall see the following messages: ``` Running hello.elf ... [OK] Running puzzle.elf ... [OK] Running pi.elf ... [OK] ``` Run `hello.elf` using the command line below: ```shell $ build/rv32emu build/hello.elf ``` ## Using GNU Toolchain - [ ] [objdump](http://man7.org/linux/man-pages/man1/objdump.1.html) > `-d` : Display the assembler mnemonics for the machine instructions ```shell $ riscv-none-elf-objdump -d build/hello.elf ``` Expected output: ``` build/hello.elf: file format elf32-littleriscv Disassembly of section .text: 00000000 <.text>: 0: 00000293 li t0,0 4: 00500313 li t1,5 8: 0040006f j 0xc c: 00000013 nop 10: 02628263 beq t0,t1,0x34 14: 04000893 li a7,64 18: 00100513 li a0,1 1c: 00000597 auipc a1,0x0 20: 02458593 addi a1,a1,36 # 0x40 24: 00d00613 li a2,13 28: 00000073 ecall 2c: 00128293 addi t0,t0,1 30: fe1ff06f j 0x10 34: 05d00893 li a7,93 38: 00000513 li a0,0 3c: 00000073 ecall 40: 6548 .2byte 0x6548 42: 6c6c .2byte 0x6c6c 44: 6f57206f j 0x72f38 48: 6c72 .2byte 0x6c72 4a: 2164 .2byte 0x2164 4c: 000a .2byte 0xa ... ``` - [ ] [readelf](http://man7.org/linux/man-pages/man1/readelf.1.html) > `-h` : Display the ELF file header ```shell $ riscv-none-elf-readelf -h build/hello.elf ``` Expected output: ``` ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: RISC-V Version: 0x1 Entry point address: 0x0 Start of program headers: 52 (bytes into file) Start of section headers: 4240 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 2 Size of section headers: 40 (bytes) Number of section headers: 4 Section header string table index: 3 ``` - [ ] [size](http://man7.org/linux/man-pages/man1/size.1.html) > list the section sizes---and the total size---for each of the object or archive files objfile in its argument list. ```shell $ riscv-none-elf-size build/hello.elf ``` Expected output: ``` text data bss dec hex filename 80 0 0 80 50 build/hello.elf ``` ## Rebuild Hello World from scratch ```shell $ cd tests/asm-hello $ make ``` File `hello.elf` should be generated if the above succeeds. The following flags should be recognized by you. * `-march=rv32i` : Specify RV32I instruction set architecture. * `-mabi=ilp32` : Specify [ILP32 ABI](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc).