- PetaLinux provee kernel, device tree y rootfs listos para personalizar en Zynq/ZynqMP.
- El flujo real combina Vivado (XSA), PetaLinux (imagen) y Vitis/SDK (app).
- El Device Tree refleja el mapa de direcciones e interrupciones definido en Vivado.
- UIO/drivers facilitan el acceso a IP; FPGA Manager agiliza iteraciones del PL.
Si te estás peleando con PetaLinux, tranquilo: no eres el único. curva de aprendizaje empinada, pero hay un camino claro para entender cómo se combinan Vivado, PetaLinux y Vitis, y qué rol juega cada pieza. Aquí vas a encontrar una explicación práctica y ordenada para que consigas pasar de un diseño en Vivado a ejecutar tu primera aplicación en Linux sobre Zynq o Zynq UltraScale+ sin morir en el intento.
Mucha gente se pregunta si se puede «vivir» solo dentro de Vitis. necesitas PetaLinux para kernel, device tree y rootfs. El flujo típico que verás en equipos reales es: generar el .xsa en Vivado, crear y configurar el proyecto PetaLinux (a veces desde un BSP), compilar y empaquetar la imagen (WIC para SD), y luego exportar el sysroot para desarrollar la app en Vitis o con un toolchain externo. Más adelante te explico alternativas, consejos para evitar reconstrucciones eternas y qué hacer con cosas como FPGA Manager o TCF Agent.
Qué es PetaLinux y qué incluye por defecto
PetaLinux es una distribución de referencia de AMD pensada para sus SoCs y MPSoCs, que te entrega un entorno Linux listo para personalizar. cargadores de arranque y kernel optimizado, bibliotecas y utilidades, soporte para C/C++ y herramientas de depuración. Además, viene con opciones de hilos, FPU y un servidor web de administración para configurar red y firmware de forma sencilla.
Los BSP oficiales suelen traer imágenes de arranque y configuración prehechas. desplegar e iniciar los binarios en hardware real o en QEMU, el emulador de sistema completo que acompaña a PetaLinux. Eso acelera la prueba inicial y es ideal para comprobar que el proyecto arranca antes de meterte con apps o drivers.
Flujos de trabajo recomendados hardware-software
En entornos profesionales se manejan dos sabores del flujo Linux: uno centrado en la línea de comandos de PetaLinux, y otro que integra Vitis para el desarrollo de aplicaciones. generando el archivo .xsa y, si procede, el bitstream.
¿Puedo hacer todo en Vitis? Para Linux, no. Vitis es magnífico para crear plataformas cuando necesitas kernel, device tree y rootfs personalizados. Lo habitual es: PetaLinux para construir el sistema y exportar el SDK/sysroot; Vitis o un toolchain externo para compilar y depurar tu aplicación.
Del XSA al sistema que arranca
El itinerario mínimo viable suele ser así: generas el .xsa en Vivado, creas el proyecto con petalinux-create (o partiendo de un BSP), actualizas el hardware en PetaLinux con ese .xsa y ajustas la configuración (kernel, device tree y rootfs). Después compilas, empaquetas a formato .wic y flasheas la tarjeta SD.
Con el sistema arrancando, llega el turno de la aplicación. exportas el sysroot/SDK desde PetaLinux y, en Vitis, creas una plataforma desde el .xsa. A partir de ahí, generas tu proyecto de aplicación C/C++ apuntando al sysroot para enlazar correctamente con las librerías del rootfs, y ejecutas la app en destino con tcf-agent, gdbserver o el método que prefieras.
Pequeña advertencia de la vida real: versiones de Vivado/Vitis/PetaLinux tienen sus peculiaridades. Por ejemplo, se ha reportado un problema en Vitis Unified 2023.2 que impide conectar con tcf-agent, y la salida rápida era pasar a 2024.1. Siempre revisa las notas de la versión y, si puedes, congela el stack de herramientas durante un proyecto.
Diseño de hardware en Vivado (Zynq-7000 y Zynq UltraScale+)
Tu base tecnológica está en el Block Design de Vivado. añade el bloque “ZYNQ7 Processing System” (o su equivalente en ZynqMP) y lanza Run Block Automation para cablear DRAM y reloj. Desde ahí, ajusta lo que vas a necesitar.
- Habilita interrupciones externas: en la personalización del PS, activa PS-PL Interrupts y Shared Interrupts si prevés compartir líneas de IRQ entre periféricos del PL.
- Sincroniza relojes: una práctica común es conectar FCLK_CLK0 al puerto M_AXI_GP0_ACLK para que el reloj del bus AXI sea coherente con el del PS.
Con los IP del PL, apóyate en la automatización. Run Connection Automation te coloca interconexiones AXI y arbitraje, pero ojo: no conecta las interrupciones ni todos los árboles de reloj. Para las IRQ, usa un bloque concat y enruta su salida al PS.
- Conecta cada línea de IRQ de tus IP periféricos al bloque Concat.
- Conecta la salida de Concat a la entrada de interrupciones del PS.
Si te conviene una memoria rápida en el PL, añade BRAM. Inserta BRAM Controller y Block Memory Generator, define número de puertos, anchura y capacidad y, muy importante, revisa su mapeo en Address Editor.
- Comprueba y ajusta el mapa de direcciones: no pueden existir solapes de rangos; si los hay, Vivado colorea en rojo el conflicto.
- Ten en cuenta otros maestros (por ejemplo, un coprocesador en el PL). Asignar direcciones es obligatorio para que la síntesis no falle.
Para cerrar el diseño, crea el wrapper HDL del .bd, sintetiza e implementa. La generación del bitstream puede tardar bastante, y al terminar exporta el hardware incluyendo el bit si quieres programar el PL desde el arranque.
Algunas matizaciones útiles: exponer señales del PS hacia el PL con EMIO para GPIO o I2C, muy práctico si, por ejemplo, vas a usar un shield PYNQ. Ojo con los periféricos integrados: suelen estar cableados a pines fijos del dispositivo y no siempre es posible sustituirlos por IP del tejido sin cambiar conexiones. Si la implementación falla, revisa restricciones (XDC) y asignaciones.
Árbol de dispositivos y mapeo de hardware
La pregunta del millón: ¿hasta dónde te abstrae Linux? Device Tree que describe direcciones, IRQ y compatibilidades de los dispositivos. Ese mapeo no es “dinámico” en el arranque salvo que utilices overlays; normalmente es estático y deriva del Address Editor de Vivado y del DTS que genera PetaLinux.
La parte de control (registros) y la de datos (por ejemplo, accesos DMA) conviene separarla conceptual y físicamente. rangos “reg” e interrupt-lines. El driver (o UIO) usará esa información para mapear memoria y la lógica de interrupciones. El tamaño y alineación de los rangos debe coincidir con lo que definiste en Vivado.
Si compilas con PetaLinux, los fragmentos DTS suelen autogenerarse del .xsa. actualizar el .xsa cuando cambias el hardware (nuevos IP o direcciones) y reconstruir al menos device tree y kernel. El rootfs no siempre necesita cambios, y por tanto el sysroot puede seguir valiendo si las librerías de usuario no se han modificado.
Opciones para acceder al hardware desde C/C++
No existe una única vía; escoge según el estado de tu proyecto y el esfuerzo que quieras dedicar a drivers. /dev/mem para mapeos MMIO, pero no es recomendable en producción por seguridad, portabilidad e interrupciones.
Alternativa intermedia: UIO (Userspace I/O) te permite mapear regiones de IP en espacio de usuario y gestionar interrupciones con select/poll. Requiere añadir los nodos UIO al Device Tree, pero evita escribir un driver completo.
La opción profesional es crear un driver de carácter o un plataforma-driver para tu IP. driver de carácter Obtienes control fino de DMA, IRQ, energía y una interfaz estable en /dev, además de mejor integración con el ecosistema del kernel. Si tu IP usa AXI-DMA o frameworks estándar, apóyate en los drivers ya existentes.
Sobre la toolchain: puedes usar Vitis o compilar con el SDK exportado por PetaLinux. petalinux-build –sdk y vincula tu proyecto a ese sysroot para asegurar que enlazas con las mismas bibliotecas que hay en el rootfs del objetivo. Vitis simplifica crear la plataforma a partir del .xsa y lanzar depuración remota.
Depuración y ejecución remota
Para ejecutar la app en el objetivo tienes varias opciones. tcf-agent funciona bien para lanzar y depurar desde Vitis, siempre que el agente esté instalado en el rootfs (añádelo desde petalinux-config -c rootfs) y no tengas un cruce de versiones.
Alternativamente, gdbserver es sencillo y robusto. Copias tu binario al objetivo, ejecutas gdbserver :port ./tuapp y te conectas desde el host con el gdb multiarquitectura. Muchos equipos combinan gdbserver con VS Code Remote o con scripts de Python.
Como recurso para ir más allá de los printf, echa un vistazo a técnicas de profiling y trazas del kernel. profiling y trazas del kernel La comunidad de Zynq ha compartido buenas prácticas para depuración eficiente que te ahorrarán tiempo cuando los fallos no sean evidentes.
Actualizar hardware sin reconstruirlo todo
Es normal pensar que un cambio en el PL obliga a «rehacer el mundo», pero hay margen. interfaces visibles al kernel (direcciones, IRQ, compatibilidad), el rootfs y el sysroot suelen seguir vigentes. En ese caso, puedes reprogramar el PL y listo.
Para cargar bitstreams en caliente, Linux ofrece el framework FPGA Manager. fpgautil o la interfaz de sysfs/configfs para programar el PL desde user space. Esto evita regenerar imágenes completas y acelera iteraciones de lógica.
Si el cambio de hardware introduce nuevos IP o modifica rangos/IRQ, entonces sí: reconstruye el device tree y vuelve a generar BOOT.BIN/imagen. Aun así, aprovecha el sstate cache para que la compilación no repita tareas ya cumplidas.
Trucos para acelerar compilaciones y ganar estabilidad
La mejor medicina contra «reconstruye todo» es la caché y el orden. sstate mirror y un directorio de descargas compartido para Yocto/PetaLinux; así evitas recompilar paquetes que no han cambiado. Esto marca la diferencia en equipos grandes y CI.
Cuida la reproducibilidad: ancla versiones de Vivado/Vitis/PetaLinux y documenta los parches. Si puedes, no cambies de versión en mitad del proyecto salvo que sea por un bug crítico confirmado. Y antes de saltar de versión, prueba en una rama.
QEMU es tu aliado. QEMU Arranca la imagen en QEMU para validar que el rootfs y el kernel hacen lo esperado sin necesidad de flashear SD. No reemplaza al hardware real, pero ahorra ciclos al comienzo.
Tras todo lo anterior, el panorama deja de parecer un rompecabezas. distro de referencia completa (bootloader, kernel, rootfs y herramientas), Vivado define el mapa físico y Vitis acelera el ciclo de app y depuración. A partir de ahí, apoyarte en Device Tree, UIO o drivers marca la diferencia entre un «Hello World» y una aplicación sólida que exprima tu hardware sin fricciones.
Redactor apasionado del mundo de los bytes y la tecnología en general. Me encanta compartir mis conocimientos a través de la escritura, y eso es lo que haré en este blog, mostrarte todo lo más interesante sobre gadgets, software, hardware, tendencias tecnológicas, y más. Mi objetivo es ayudarte a navegar por el mundo digital de forma sencilla y entretenida.