Uno de los objetivos que siempre se tiene al trabajar con sistemas embebidos es correr un sistema operativo (OS), y siempre hay uno por excelencia para este tipo de plataformas —y más importante aún, de software libre— como lo es Linux, además de que existen muchas herramientas que nos ayudan a adaptar el sistema a nuestras necesidades.
Limitaciones de la Tang Nano 20K
Bueno, la Tang Nano 20K es bastante limitada en conceptos de FPGA, algo entendible al tratarse de una FPGA de bajo costo. La principal limitación es la RAM disponible, ya que lo máximo que podemos generar es 8 MiB, por lo cual nuestro Linux debe ser bastante conservador en ese sentido.
Buildroot
Para compilar nuestro sistema operativo vamos a usar la herramienta Buildroot, lo cual simplifica bastante la tarea —aunque sigue siendo agotadora. Por eso dejaré los archivos precompilados para que puedas saltarte este paso. En un post más adelante explicaré cómo se crean y modifican estos archivos para que puedas generar tu propio kernel.
Linux-on-LiteX
Este es un proyecto que nos proporciona la configuración necesaria para que Buildroot pueda compilar correctamente la imagen y binarios que correrán en el SoC de LiteX, el cual vamos a implementar en nuestra Tang Nano 20K. Como mencioné anteriormente, todo este trabajo ya lo hice, por lo cual no es necesario que lo repitas, aunque si deseas puedes compilar tu propia versión (eso sí, tomará unas cuantas horas).
LiteX
La base de toda esta serie. No hay mucho que agregar sobre LiteX, ya lo he explicado en publicaciones anteriores. En este caso también he hecho la mayor parte del trabajo: configuré un script que genera una CPU RISC-V rv32 compatible con Linux y que puede montarse en la Tang Nano 20K. Por lo tanto, solo debes generar el bitstream o usar el precompilado que dejaré, y subirlo a tu Tang Nano. Con esto, si te conectas por litex-term
, podrás ver que tiene soporte para boot desde SD. También se puede hacer el boot por serial, pero es demasiado lento y no tengo tiempo para eso.
La SD
Como mencioné, booteamos desde una SD, porque es la forma más rápida para este caso. Lo importante es que esté en formato FAT y contenga los archivos necesarios para el correcto funcionamiento del kernel:
boot.json
: Define dónde y cuáles archivos se cargarán en la memoria RAM de la FPGA.Image
: Es nuestro sistema operativo.opensbi.bin.tangnano20k
: Es la BIOS encargada de cargar Linux.rv32.dtb
: Es la definición de la placa con sus periféricos. Con estos archivos en la SD, solo es cuestión de iniciar la FPGA y booterla consdcardboot
, en caso de que no lo haga automáticamente.
Corriendo Linux
Ya he preparado todo lo necesario para que puedas ejecutar Linux sobre la Tang Nano sin muchas complicaciones. En próximos artículos exploraremos cómo modificar nuestro sistema para poder hacer más cosas, pero para comenzar, no se necesita más que ejecutar el siguiente comando desde la carpeta del repositorio litex-linux
:
python3 linux_tang.py --build --load
O, si deseas que quede grabado permanentemente en la memoria:
python3 linux_tang.py --build --flash
Después, debes conectarte mediante litex_term
, sin insertar aún la tarjeta SD. Deberías ver algo como esto:
litex> help
LiteX BIOS, available commands:
leds - Set Leds value
buttons - Get Buttons value
flush_l2_cache - Flush L2 cache
flush_cpu_dcache - Flush CPU data cache
crc - Compute CRC32 of a part of the address space
ident - Identifier of the system
help - Print this help
sdcardboot - Boot from SDCard
serialboot - Boot from Serial (SFL)
reboot - Reboot
boot - Boot from Memory
mem_cmp - Compare memory content
mem_speed - Test memory speed
mem_test - Test memory access
mem_copy - Copy address space
mem_write - Write address space
mem_read - Read address space
mem_list - List available memory regions
sdram_mr_write - Write SDRAM Mode Register
sdram_test - Test SDRAM
sdram_init - Initialize SDRAM (Init + Calibration)
sdcard_write - Write SDCard block
sdcard_read - Read SDCard block
sdcard_freq - Set SDCard clock freq
sdcard_init - Initialize SDCard
sdcard_detect - Detect SDCard
Ahora inserta la tarjeta SD y escribe el comando:
sdcardboot
Si todo sale bien, deberías ver algo similar a esto, lo cual indica que ya estás corriendo Linux.
Booting from SDCard in SD-Mode...
Booting from boot.json...
Copying Image to 0x40000000 (1818868 bytes)...
[########################################]
Copying sipeed_tang_nano_20k.dtb to 0x40780000 (2115 bytes)...
[########################################]
Copying opensbi.bin.tangnano20k to 0x407c0000 (49636 bytes)...
[########################################]
Executing booted program at 0x407c0000
--============= Liftoff! ===============--
OpenSBI v0.8-2-ga9ce3ad
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : LiteX / VexRiscv-SMP
Platform Features : timer,mfdeleg
Platform HART Count : 8
Boot HART ID : 0
Boot HART ISA : rv32imasu
BOOT HART Features : pmp,time
BOOT HART PMP Count : 16
Firmware Base : 0x407c0000
Firmware Size : 120 KB
Runtime SBI Version : 0.2
MIDELEG : 0x00000222
MEDELEG : 0x0000b109
[ 0.000000] Linux version 6.4.0-rc1+ (zjs@CL-A-00022) (riscv64-linux-gnu-gcc (Debian 12.2.0-13) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #10 Tue May 16 09:20:49 CST 2023
Los archivos
Como mencioné, ya realicé la compilación de los archivos, así que no tienes que reinventar la rueda. Todos los archivos están disponibles en mi repositorio.
- En la carpeta
software/
están los archivos que van en tu SD. - En
misc/
encontrarás el script para subir y generar el bitstream. - Si prefieres usar un bitstream ya precompilado, este está dentro de
firmware/
.