Snake em C bare-metal para RISC-V 32-bit, rodando no emulador QEMU (máquina virt).
- QEMU (
qemu-system-riscv32) - LLVM com alvo RISC-V + lld
- Um compilador C
brew install qemu llvm lldO Makefile assume (Apple Silicon):
- Clang:
/opt/homebrew/opt/llvm/bin/clang - Linker:
/opt/homebrew/bin/ld.lld
Se estiver em Intel Mac, ajuste:
export LLVM_BIN=/usr/local/opt/llvm/bin
export LLD=/usr/local/bin/ld.lld# Debian/Ubuntu (exemplo)
sudo apt install qemu-system-misc clang lld makeNo Linux o display padrão do make run é cocoa (macOS). Rode assim:
make
qemu-system-riscv32 -machine virt -bios none -kernel build/snake.elf \
-device virtio-gpu-device \
-device virtio-keyboard-device \
-display sdl \
-serial stdio \
-semihosting-config enable=on,target=native(Ou edite a linha -display cocoa no Makefile para -display sdl.)
O caminho mais simples é usar o WSL2 (Ubuntu) e seguir os passos de Linux.
- Instale o WSL, se ainda não tiver (PowerShell como administrador):
wsl --install- Abra o Ubuntu no WSL e instale as dependências:
sudo apt update
sudo apt install qemu-system-misc clang lld make- Entre na pasta do projeto (ex.: se o repo estiver em
C:\Users\voce\snake-game):
cd /mnt/c/Users/voce/snake-game- Compile e rode (com display SDL, não cocoa):
make
qemu-system-riscv32 -machine virt -bios none -kernel build/snake.elf \
-device virtio-gpu-device \
-device virtio-keyboard-device \
-display sdl \
-serial stdio \
-semihosting-config enable=on,target=nativeJanela gráfica no WSL: use WSLg (Windows 11 costuma trazer isso) ou um servidor X. Sem isso, o -display sdl pode falhar — nesse caso atualize o WSL (wsl --update) ou rode só com serial:
qemu-system-riscv32 -machine virt -bios none -kernel build/snake.elf \
-device virtio-gpu-device \
-device virtio-keyboard-device \
-display none \
-serial stdio \
-semihosting-config enable=on,target=native(Com -display none não há pixels; use só para validar o boot pelo terminal.)
Alternativa sem WSL: instale MSYS2, abra o terminal UCRT64 e:
pacman -S make mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-lld mingw-w64-ucrt-x86_64-qemuAjuste no Makefile os caminhos LLVM_BIN / LLD / QEMU para os binários do MSYS2 e troque -display cocoa por -display sdl.
No diretório do projeto:
# 1) Compilar o jogo RISC-V
make
# 2) Abrir no QEMU
make runIsso gera build/snake.elf e sobe o QEMU
make # só compila
make test # testes (snake, velocidade, scores)
make run # compila se preciso e abre o QEMU
make clean # apaga build/src/ código do jogo + drivers (UART, VirtIO-GPU, teclado, semihosting)
tests/ testes unitários no host
link.ld linker script (RAM em 0x80000000)
Makefile build cross + run no QEMU
No bare-metal não há sistema operacional nem biblioteca tipo SDL no guest. O QEMU só oferece uma placa de vídeo virtual (VirtIO-GPU). Sem um driver, o programa não consegue pintar pixels na janela.
O src/virtio_gpu.c faz exatamente isso:
- Encontra o dispositivo VirtIO-GPU nos endereços MMIO da máquina
virt - Configura a fila de comandos (virtqueue legada)
- Cria um framebuffer RGB na RAM do guest
- Envia comandos (
RESOURCE_CREATE_2D,ATTACH_BACKING,SET_SCANOUT,TRANSFER,FLUSH) - Expõe o buffer para o resto do jogo (
fb.c/ menu / cobrinha) desenhar e chamarvirtio_gpu_flush()
Em resumo: a lógica do Snake só escreve cores na memória; o virtio_gpu.c é o que faz o QEMU mostrar essa memória como a janela gráfica (as screenshots acima).
O teclado da janela segue a mesma ideia em src/virtio_input.c (VirtIO keyboard). A UART (uart.c) continua como fallback no terminal.

