---
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).