Configurando a toolchain e o QEMU

1. TL;DR


2. Antes de começar

Todos os arquivos-fonte estão disponíveis no GitHub RISC-V Experiments Repository.

3. Ferramentas necessárias

Precisamos do compilador cruzado GCC para RISC-V, QEMU, GDB e algumas ferramentas padrão de build. No Ubuntu 24.04 (ou sistemas baseados em Debian), instale com:

1
2
3
4
5
6
sudo apt update
sudo apt install build-essential \
  gcc-riscv64-unknown-elf \
  gdb-multiarch \
  qemu-system-riscv32 \
  binutils-riscv64-unknown-elf

3.1. Instalar o Pwndbg

Pwndbg é um plug-in poderoso do GDB que fornece uma interface melhor para engenharia reversa e depuração. Ele será útil para inspecionar registradores e memória em capítulos posteriores.

1
2
3
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

4. Estrutura do projeto

1
2
3
git clone https://github.com/psylinux/riscv-experiments.git
cd riscv-experiments
mkdir -p build
1
2
3
4
riscv-experiments/
  docs/
  src/
  build/

5. “Hello” mínimo na UART

Arquivo: src/hello_uart.c

1
2
3
4
5
6
7
#include "types.h"
#include "uart.h"

int main(void) {
  uart_puts("Hello from RV32 in QEMU!\n");
  return 0;
}

Compile e rode:

1
2
3
4
5
riscv64-unknown-elf-gcc -O0 -g -ffreestanding -nostdlib \
  -march=rv32im -mabi=ilp32 -T src/link.ld \
  src/start.s src/uart.c src/hello_uart.c -o build/hello_uart.elf

qemu-system-riscv32 -M virt -nographic -bios none -kernel build/hello_uart.elf

Você deve ver a mensagem no terminal.

6. Rodando com GDB

Inicie o QEMU em modo pausado:

1
2
qemu-system-riscv32 -S -M virt -nographic -bios none \
  -kernel build/hello_uart.elf -gdb tcp::1234

Conecte em outro terminal:

1
2
3
4
5
gdb-multiarch build/hello_uart.elf \
  -ex "set arch riscv:rv32" \
  -ex "target remote localhost:1234" \
  -ex "break main" \
  -ex "continue"

7. Exercícios

  1. Confirme que você consegue rodar qemu-system-riscv32 --version no seu sistema.
  2. Confirme que você consegue rodar riscv64-unknown-elf-gcc --version no seu sistema.
  3. Verifique se consegue usar make rodando make --version.
  4. Verifique se consegue rodar gdb-multiarch rodando gdb-multiarch --version.
  5. Mude a string e verifique que ela imprime corretamente.
  6. Adicione uma segunda linha uart_puts e faça passo a passo no GDB.

8. Resumo