2021/09/09

H4CK3D 2021: configuración básica

Otra vez tengo el honor, privilegio, gusto, placer, como lo quieras llamar de exponer en H4CK3D, organizado por Securetia y la UP, donde me dicen "exponé lo que quieras", no sé si eso habla bien de ellos, yo no me daría tanta confianza, la vez que me dijeron eso en el trabajo para una charla interna, expuse sobre "chistes nerds", muy divertido pero a la gente más seria no le pareció tan simpático.

El año pasado mostré una POC de malware en hardware (empieza cerca de 0:14:00 y dura hasta 1:13:00), este año tambien, pero será otro "modelo". Esa vez fue un ejemplo basado en un ataque propuesto existente, afectar el bit supervisor según una pista que normalmente tiene poca activida pero una operación infrecuente artificialmente ejecutada de modo desproporcionado termina seteándolo.

La POC de este año será un poco más complicada, los detalles los iré agregando más adelante, esta entrada ya es bastante larga y no quiero spoilers.

Aunque falta bastante tiempo no puedo garantizar que pueda armar la POC, no estoy seguro de que ni sea factible ni que yo pueda realizarla, asi que propuse un Plan B, que fue aceptado.

Pero no, me he dicho, todo o nada, o voy a llegar con una POC exitosa o pondré la cara y explicaré los motivos de la falla. La posibilidad de un Plan B habilitaria el escenario de sucumbir a la desesperación y no esforzarme lo suficiente para lograr que funcione. Además, el Plan B que tengo es bastante triste, no cumple siquiera con mis más bajos standards.

El Plan B es el Plan A.

Mientras, voy a ir exponiendo el backstage, es un montón de tiempo y trabajo y deseo compartirlo, pero es muy heavy para la charla en sí, necesitaría como dos horas. Yo no, pero la mayor parte se aburriría hasta morir.

En esta entrada voy a sentar las bases, hacer funcionar el stack para desplegar en una EDU-CIAA-FPGA una CPU RISC-V RV32I con un programa en su memoria.

En las siguientes, las modificaciones necesarias para implementar la POC. Luego será el evento y finalmente como ya es costumbre, the missing pieces, con todo lo que me haya olvidado de poner en la presentación u olvidado de decir en el momento.

 

Sistema operativo


Una máquina virtual con virtualbox, Linux Mint 20.1 Mate, 2 cores, 8 GB RAM, 30 GB disco.

No respeté mi regla de usar más cores y memoria durante la instalación y volver a algo más reducido en el proyecto, debo haber perdido algunas horas. Tampoco le atiné al espacio de disco y tuve que desmalezar en algún momento. La memoria sobró en todo momento.

 

Stack


Hace meses había hecho unas pruebas sobre las instrucciones del sitio del proyecto, dí mi feedback pero no recuerdo nada, así que tomé como punto de partida la exposición de Rodrigo Melo de FOSS para FPGA, con su presentanción y repositorio, pero no, usa docker y vhdl. Si es tu primer contacto con la EDU-CIAA-FPGA o con FPGA, no desprecies este recurso ni el canal ni toda la info que tiene el proyecto, yo ya ví las charlas y algo sé de antes y tengo una idea para donde ir.

Luego, me apoyé en la exposición de Pablo Ridolfi, RISC-V con EDU CIAA FPGA, su presentación y repositorio, que es un fork de la CPU original adaptado a la placa. Cuando ví esta exposición supe que debía usar RISC-V en lugar de cualquier otra opción, ya volveré sobre eso en futuras entradas.

Me bajé también el repo de ejemplos, por las dudas.

Use este scriptcito para comprobar que había armado bien la jerarquía de repos, pues cuando empecé estaban tirados en el desktop, de paso repasamos un poco de bash:

find . -iname config | while read CONFIG; do
   echo -n "$CONFIG "
   grep url "$CONFIG"
done

No recuerdo en detalle la charla de Pablo, podría revisarla o leer el README.md y mejor aún el EDU-FPGA.md, prefiero tomar el camino más difícil para comprender mejor. Esto sale de la lista de dependencias:

 

  • GNU Make
    • ya viene instalado.
  • vim (for xxd)       
    • ya viene instalado, en realidad vi provee xxd, luego yo uso vim.

  • Icarus Verilog
    • git clone git://github.com/steveicarus/iverilog.git
    • sh autoconf.sh
    • ./configure
    • make -j2
    • 5 minutos
    • sudo make install
  • Project IceStorm or Project Trellis, vamos por icestorm
    • http://www.clifford.at/icestorm/
    • git clone https://github.com/YosysHQ/icestorm.git
    • make -j2
    • 3 minutos
    • sudo make install       
  • nextpnr or arachne-pnr, vamos por nextpnr
    • git clone https://github.com/YosysHQ/nextpnr
    • requiere que antes esté instalado icestorm
    • cmake -DARCH=ice40 -DCMAKE_INSTALL_PREFIX=/usr/local .
    • make
    • 17  minutos
    • sudo make install        
  • Yosys
    • git clone https://github.com/YosysHQ/yosys.git
    • make config-gcc
    • make
    • 45  minutos
    • sudo make install
  • GNU RISC-V toolchain
    • Esto merece párrafo aparte 

 

El repositorio tiene 6.5GB, pude haberlo bajado en lugar de clonarlo o instalar lo que viene con la distro con:

 

sudo apt install gcc-riscv64-unknown-elf

 

Tenía dudas respecto a 32/64 bits, pero por ahí dice:

"The multilib compiler will have the prefix
riscv64-unknown-elf- or riscv64-unknown-linux-gnu-,
but will be able to target both 32-bit and 64-bit systems."

 

Mala idea este camino, al ejecutar:

 

$ make BOARD=edufpga
icepll -q -i 12 -o 36 -m -f pll.sv
icebram -g 32 2048 > progmem_syn.hex
riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -Wall -Wextra -pedantic -DFREQ=36000000 -Os -ffreestanding -nostartfiles -g -Iprograms/hello   -c -o programs/hello/main.o programs/hello/main.c
cp start-ram.s start.s
riscv64-unknown-elf-as -march=rv32i -mabi=ilp32  -o start.o start.s
cp arch/ice40-ram.lds progmem.lds
riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -Wall -Wextra -pedantic -DFREQ=36000000 -Os -ffreestanding -nostartfiles -g -Iprograms/hello -Wl,-Tprogmem.lds -o progmem programs/hello/main.o start.o
/usr/lib/riscv64-unknown-elf/bin/ld: cannot find -lc
/usr/lib/riscv64-unknown-elf/bin/ld: cannot find -lgloss

 

Hallé en esta conversación de 2017 que libgloss no debería ser incluido, que newlib (uno de los submodules de riscv64)... suficiente, demasiado complicado, tras eliminar gcc-riscv64-unknown-elf, a clonar:
   

  • git clone --recursive \
    https://github.com/riscv/riscv-gnu-toolchain.git
  • ./configure
  • sudo make -j2
  • 130 minutos

      
¿perfecto? No, 30 GB no alcanzan para nada más, terminó y murio.

 

$ cd REPO
find . -type d -iname ".git" -exec du -sh {} \;
217M   ./gitlab/educiaafpga/ejemplos/.git
472K   ./github/ciaa/icicle/.git
4,0G   ./github/riscv/riscv-gnu-toolchain/.git
28M    ./github/steveicarus/iverilog/.git
464K   ./github/grahamedgecombe/icicle/.git
8,9M   ./github/rodrigomelo9/FOSS-for-FPGAs/.git
23M    ./github/YosysHQ/yosys/.git
44M    ./github/YosysHQ/yosys/abc/.git
2,8M   ./github/YosysHQ/icestorm/.git
11M    ./github/YosysHQ/nextpnr/.git



Revisando a manito, todos están en master o main, puedo hacer make clean y volar los .git en todos menos en los que pueda llegar a modificar algo. De un modo u otro recuperé 3GB y pude ir a ciaa/icicle y

 

make BOARD=edufpga

 
¡éxitos!

Si tomaras este camino y estuvieras con poco espacio, te recomendaría este orden:

  • GNU RISC-V toolchain, tras el install, borrar
  • luego
    • Project IceStorm
    • nextpnr, tras el install, borrar ambos
  • luego
    • Icarus Verilog, tras el install, borrar
    • Yosys, tras el install, borrar
  • luego
    • clonar icicle/o el mío

 

Veamos de grabar:

 

make BOARD=edufpga flash

Can't find iCE FTDI USB device (vendor_id 0x0403, device_id 0x6010 or 0x6014).

ufa! apuesto a que hay problemas de permisos y eso que Pablo seguro lo dijo... no, pero yo lo sabía:

 

$ groups
charly adm cdrom sudo dip plugdev lpadmin sambashare
$ ls -l /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0 Sep  7 18:14 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 Sep  7 18:14 /dev/ttyUSB1

 

Se arregla muy fácil:

$ sudo addgroup charly dialout
[sudo] password for charly:             
Adding user `charly' to group `dialout' ...
Adding user charly to group dialout
Done.
$ su - charly
Password:
$ groups
charly adm dialout cdrom sudo dip plugdev lpadmin sambashare

 

en teoría desde el su es para no reiniciar la sesión entera

make BOARD=edufpga flash

...nada, lo peor es que con sudo si funciona, grrrrr... no es un problema bloqueante pero me ofende.

Logout/login... sigue fallando, mmmh, interesante, sólo falla iceprog, con gtkterm o con cat no hay problema:

$ cat /dev/ttyUSB1
Hello, world!

Hello, world!

Hello, world!


Un poquito de stackoverflow y solucionado, hay que agregar una regla para udev y reiniciar el servicio y seguimos practicando bash:

 

echo 'ACTION=="add", ATTR{idVendor}=="0403", ATTR{idProduct}=="6010", MODE:="666"' |\
sudo tee -a /etc/udev/rules.d/70-lattice.rules 1>/dev/null

 

sudo service udev restart

Listo, igual aquí hubo algo que no terminé de entender, me parece que la clave es MODE:="666" y que ya he lidiado con este asunto pero no puedo recordar...


Probé salirme del grupo dialout y alcanza con lo de udev para flashear, pero necesitás los permisos para interactuar desde cat y gtkterm.


 

Hello World
Hello World

Ah, hablando de recordar, una trampa por si venías copiando, pegando y ejecutando antes de leer todo y sin pensar. Antes que nada hay que ejecutar:

$ sudo apt install gperf build-essential cmake \
   python3-dev texinfo vim libboost-all-dev tcl-dev \
   libreadline-dev libffi-dev
libeigen3-dev
 

Es lo que recolecté resultado de ir fallando en cada paso. La lista de Pablo es más generosa, pero yo quiero sólo lo indispensable para este proyecto y él además, estoy seguro que avisó que como venía probando, quizás sobraban cosas.

Si te faltaba espacio, probablemente los *-dev se puedan desinstalar luego de las compilaciones de las tools.

 

No requiere gran talento haber llegado hasta acá, sólo hice una libre interpretación de instrucciones bastante completas. Sin embargo lleva bastante tiempo, sirve para ir familiarizándose con las herramientas y es indispensable, es parte del camino no docker.

Ahora me queda pendiente leer un botón, en ciaa/icicle/boards/edufpga.pcf hay pines pero sólo de salida, seguramente me podré inspirar al ladito en icebreaker que está muy completo.

Tambien tendría que agregar algo que parezca un reloj, un divisor de frequencia conectados a unos leds, independiente de la CPU. No va a hacer falta un debouncer, ni por hardware ni por software, el programa no va a usar interrupciones para leer los botones ni le afectarán los rebotes.


Spoiler Alert: parece que icicle no tiene implementado GPIO!!!


No hay comentarios:

Publicar un comentario