--- 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 ```