---
tags: computer-arch
---
# Lab2: RISC-V `RV32I[MA]` emulator with ELF support
## [rv32emu](https://github.com/sysprog21/rv32emu)
* RISCV emulator for the RV32I architecture
* based on [TinyEMU](https://bellard.org/tinyemu/) by Fabrice Bellard, check [Lab0: Web-based Emulators](https://hackmd.io/@sysprog/SJ7ht_MuS)
* stripped down for RV32I only, all "gotos" removed, and fixed some bugs for the compliance test
## 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-embed-gcc/)
```shell
$ cd /tmp
$ wget https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.2.0-1.1/xpack-riscv-none-embed-gcc-10.2.0-1.1-linux-x64.tar.gz
$ tar zxvf xpack-riscv-none-embed-gcc-10.2.0-1.1-linux-x64.tar.gz
$ cp -af xpack-riscv-none-embed-gcc-10.2.0-1.1 $HOME/riscv-none-embed-gcc
```
2. Configure `$PATH`
```shell
$ cd $HOME/riscv-none-embed-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-embed-gcc/setenv
```
Check `$PATH` at the first time:
```shell
$ riscv-none-embed-gcc -v
```
You shall be able to see the following messages:
```
gcc version 10.1.0 (xPack GNU RISC-V Embedded GCC, 64-bit)
```
3. Fetch [rv32emu](https://github.com/sysprog21/rv32emu) and build from source
```shell
$ git clone https://github.com/sysprog21/rv32emu
$ cd rv32emu
$ make
```
4. Validate [rv32emu](https://github.com/sysprog21/rv32emu)
```shell
$ make check
```
You shall see the following messages:
```
./emu-rv32i test1
Hello RISC-V!
>>> Execution time: 29144 ns
>>> Instruction count: 62 (IPS=2127367)
>>> Jumps: 14 (22.58%) - 0 forwards, 14 backwards
>>> Branching T=13 (92.86%) F=1 (7.14%)
```
## 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-embed-objdump -d test1
```
Expected output:
```
test1: file format elf32-littleriscv
Disassembly of section .text:
00010054 <_start>:
10054: 000107b7 lui a5,0x10
10058: 07878793 addi a5,a5,120 # 10078 <_start+0x24>
1005c: 04800713 li a4,72
10060: 400026b7 lui a3,0x40002
10064: 00e68023 sb a4,0(a3) # 40002000 <__global_pointer$+0x3fff0778>
10068: 00178793 addi a5,a5,1
1006c: 0007c703 lbu a4,0(a5)
10070: fe071ae3 bnez a4,10064 <_start+0x10>
10074: 00008067 ret
```
- [ ] [readelf](http://man7.org/linux/man-pages/man1/readelf.1.html)
> `-h` : Display the ELF file header
```shell
$ riscv-none-embed-readelf -h test1
```
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: 0x10054
Start of program headers: 52 (bytes into file)
Start of section headers: 540 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 7
Section header string table index: 6
```
- [ ] [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-embed-size test1
```
Expected output:
```
text data bss dec hex filename
52 0 0 52 34 test1
```