Homelab · Raspberry Pi · NAS

Cómo perdí el acceso a mi NAS casera y lo que aprendí en el camino

Junio 2026 RPi5 + Radxa Penta SATA HAT OpenMediaVault

Era un día cualquiera cuando mi Raspberry Pi 5 se reinició sola. No era la primera vez que pasaba algo así — una bajada de tensión, un pico en la red, quién sabe. El caso es que cuando intenté acceder a mi NAS montada con OpenMediaVault, silencio total. Los discos habían desaparecido.

El primer diagnóstico

Lo primero fue conectarme por SSH y ejecutar lsblk. Solo aparecía la tarjeta SD. Ni rastro de los tres discos duros que llevaban meses ahí, guardando tranquilamente mis datos. Un lsusb tampoco mostró nada útil, lo que descartó problemas USB — pero es que mis discos van por un Penta SATA HAT de Radxa conectado por PCIe, no por USB.

El dmesg fue más revelador:

ahci 0001:01:00.0: failed to start port 0 (errno=-12)
ahci 0001:01:00.0: probe with driver ahci failed with error -12

El controlador SATA JMicron JMB585 del HAT se detectaba por PCIe, pero fallaba al inicializarse. El errno=-12 significa ENOMEM — sin memoria. Raro, porque la RPi5 tiene 4GB.

El cmdline corrupto

Mirando más de cerca, encontré el primer culpable real: el archivo /boot/firmware/cmdline.txt estaba gravemente corrupto. Contenía algo así:

console=serial0,1tail -5 /boot/firmware/config.txtb04c8b86-02 rootfstype=ext4...

Comandos de terminal literalmente mezclados dentro del archivo de configuración de arranque. Lo que había pasado era que en el momento del reinicio forzado —por falta de memoria— el sistema volcó entradas de la terminal dentro del archivo durante el apagado abrupto.

Reconstruí el cmdline limpiamente y reinicié con esperanza.

La memoria CMA

El error persistía. Investigando más, encontré que la memoria CMA — la región de memoria contigua reservada para DMA — estaba prácticamente agotada:

CmaTotal:  65536 kB
CmaFree:   448 kB   ← casi cero

El JMB585 necesita memoria DMA para inicializarse, y no había. Aumenté la CMA a 256MB añadiendo cma=256M al cmdline. Pero el error seguía.

La tormenta perfecta

Después de horas probando parámetros, overlays y combinaciones varias, llegué a la conclusión: habían coincidido varios problemas a la vez.

01 La RPi petó por falta de memoria con demasiados servicios corriendo
02 El apagado abrupto corrompió el cmdline.txt
03 Al reiniciar, el sistema cogió el kernel nuevo que ya tenía instalado (6.12.87)
04 Ese kernel tiene un cambio de comportamiento con el JMB585 que requiere configuración adicional
Nota El sistema llevaba más de un año funcionando sin problemas con el kernel 6.12.75. Cualquiera de estos problemas por separado habría sido fácil de diagnosticar. Juntos crearon un caos de síntomas contradictorios que apuntaban en todas direcciones.

La solución

La solución fue sorprendentemente simple. Una sola línea en /boot/firmware/config.txt:

Fix dtoverlay=pcie-32bit-dma-pi5

El JMicron JMB585 es un controlador legacy que opera en modo DMA de 32 bits. El BCM2712 de la RPi5 usa por defecto direccionamiento DMA de 64 bits. Durante más de un año esto funcionó porque los kernels anteriores manejaban la compatibilidad de forma implícita. A partir de cierto commit del kernel oficial de Raspberry Pi, el chip requiere indicárselo explícitamente. Sin ese overlay, el driver AHCI falla con ENOMEM antes de llegar siquiera a detectar los discos.

Con esa línea añadida, los tres discos aparecieron inmediatamente:

sda  →  1 TB    ✓  montado
sdb  →  500 GB  ✓  montado
sdc  →  4 TB    ✓  montado

Lecciones aprendidas

  1. Hacer snapshots o backups del /boot/firmware/ antes de actualizar el sistema. Un cmdline corrupto puede dejarte sin acceso a los datos aunque los discos estén perfectamente sanos.
  2. Las actualizaciones automáticas del kernel en un servidor de producción —aunque sea casero— deben hacerse con cuidado. El kernel puede cambiar comportamientos que llevan años funcionando silenciosamente.
  3. Cuando un sistema lleva mucho tiempo funcionando y falla tras un reinicio inesperado, casi nunca es un único problema. El diagnóstico hay que hacerlo por capas, descartando una a una, sin asumir que encontrar un problema significa haber encontrado el problema.

Los datos estaban bien. El HAT estaba bien. La RPi estaba bien. Solo necesitaba una línea de configuración y un cmdline limpio para volver a la vida.