Raspberry Pi 5 + Debian 13: La maldición de los archivos corruptos

Imagina la escena: tienes tu flamante Raspberry Pi 5, la actualizas a Debian 13 (Trixie) o instalas una derivada como MX Linux, y todo parece funcionar… hasta que intentas descargar algo grande.

  • Bajas una ISO de Linux desde el navegador, haces el sha256sum y… falla. La vuelves a descargar, el hash es diferente otra vez. Corrupta siempre.
  • Usas aMule para compartir archivos, la descarga llega feliz al 100% y de repente retrocede al 80%. Vuelve a subir, otra vez 100%, otra vez 80%… un bucle infinito de rehasheo. A veces después de horas logra completar, pero la desesperación ya te ha consumido.

Esto me pasó a mí. Y lo peor es que en Debian 12 funcionaba todo perfectamente. Probé de todo: memtest, cambiar la fuente de alimentación, revisar el NVMe, hacer fsck… nada. Hasta que por fin alguien me dio la solución mágica: dos cambios aparentemente absurdos que lo arreglaron todo.

Hoy te cuento por qué ocurría, por qué la solución funciona, y sobre todo cómo aplicarla para que nunca más sufras con descargas rotas en tu Raspberry Pi 5.

Lo que NO era (descartando lo obvio)

Antes de tirarme por la ventana, descarté lo típico:

  • Memoria RAM defectuosa – Pasó las pruebas.
  • Problemas de red – Otras máquinas descargaban el mismo archivo sin fallos.
  • Alimentación insuficiente – Usaba el cargador oficial de la Pi 5.
  • Disco duro o microSD corruptos – Ni fsck ni smartctl mostraban errores.

Era algo más raro, más profundo. Algo que había cambiado entre Debian 12 y Debian 13.

El hallazgo inesperado: el kernel de 16KB

Resulta que, para optimizar el rendimiento en procesadores modernos, algunas distribuciones de Linux para ARM64 (como las últimas versiones de Raspberry Pi OS y Debian 13) han empezado a compilar el kernel con páginas de memoria de 16KB, en lugar de las clásicas de 4KB que hemos usado toda la vida.

¿Qué significa esto? El sistema operativo divide la memoria RAM en «páginas» (como las hojas de un libro). Durante décadas el estándar fue 4KB. Pero si aumentas el tamaño a 16KB, el sistema puede manejar más datos con menos operaciones internas, lo que teórico mejora el rendimiento.

El problema es que el software del mundo real está compilado asumiendo páginas de 4KB. Navegadores, aMule, emuladores, clientes de descarga… todos ellos hacen cálculos basándose en ese tamaño. En concreto, utilizan una función del sistema llamada mmap (memory-mapped files) que es muy rápida pero muy sensible al alineamiento de las páginas.

¿Qué hace mmap y por qué se rompe?

mmap le dice al kernel: «Oye, toma este archivo del disco y proyéctalo directamente en la memoria RAM, para que pueda escribir en él a toda pastilla». Para hacerlo, el programa calcula las posiciones (offsets) en múltiplos del tamaño de página.

Si el programa usa 4KB y el kernel piensa en 16KB, los cálculos se desalinean. Los datos se escriben en posiciones incorrectas, unos encima de otros. Esto es especialmente crítico con archivos grandes (varios GB). Las ISO se descargan completas pero internamente tienen los bytes cambiados de sitio. Por eso el sha256sum nunca coincide, y por eso aMule entra en un bucle de rehasheo: detecta que los bloques no son los que deberían ser y vuelve a descargarlos una y otra vez.

Ese era el monstruo oculto bajo la cama.

La solución: dos caminos, uno definitivo

Opción 1: Cambiar el kernel al de 4KB (recomendada)

La forma más limpia y que arregla todos los programas de golpe es obligar a la Raspberry Pi a usar el kernel clásico de 64 bits con páginas de 4KB. Es muy sencillo:

  1. Abre el archivo de configuración del firmware:
   sudo nano /boot/firmware/config.txt
  1. Al final del archivo, añade esta línea:
   kernel=kernel8.img
  1. Guarda, reinicia y ya está.

¿Qué hace esa línea? El firmware de la Raspberry Pi, al arrancar, busca un kernel. kernel8.img es el kernel de 64 bits «estándar», que usa páginas de 4KB como toda la vida. Las versiones más modernas a veces usan otros nombres (como kernel8-16k.img), pero kernel8.img sigue siendo el clásico. Así que con esa instrucción le dices: «carga ese, no el que te dé la gana».

Después de reiniciar, puedes comprobar el tamaño de página activo con:

getconf PAGE_SIZE

Si ves 4096 (que son 4KB), enhorabuena. El problema ha desaparecido para siempre.

Opción 2: El parche solo para aMule (no recomendado, pero existe)

Si por alguna razón no quieres tocar el kernel, puedes recompilar aMule desactivando el uso de mmap. Así el programa usará el sistema de entrada/salida clásico, que no se ve afectado por el tamaño de página.

./configure --disable-mmap
make && sudo make install

Ojo: Esto solo arregla aMule. El navegador web y cualquier otra aplicación que use mmap seguirá descargando archivos corruptos. Por eso la opción 1 es infinitamente mejor.

Comprobación de que todo funciona

Después de aplicar la solución (la opción 1, claro), haz estas pruebas:

  • Descarga dos veces la misma ISO grande (por ejemplo, Ubuntu 24.04). Calcula el sha256sum de ambas. Deben ser idénticos y coincidir con el oficial.
  • Prueba una descarga pesada con aMule. Llegará al 100% y se quedará ahí, sin rehasheos.
  • Opcional: getconf PAGE_SIZE debe decir 4096.

¿Pierdo rendimiento usando páginas de 4KB?

En teoría, los kernels con páginas de 16KB pueden ser ligeramente más rápidos en ciertos benchmarks de memoria masiva. En la práctica, con un uso normal de escritorio, servidor casero o centro multimedia, no notarás la diferencia. Lo que sí notarás es que tus archivos se descargan correctamente. Para mí, la fiabilidad gana por goleada.

Además, hay quien dice que muchos juegos y emuladores funcionan incluso mejor con 4KB precisamente por la compatibilidad. Así que no le des más vueltas.

Preguntas frecuentes

¿Esto es seguro? ¿Puedo romper mi Raspberry Pi?
Absolutamente seguro. kernel=kernel8.img es un kernel oficial, firmado, estable. No es overclock ni modificación extraña.

¿Qué pasa si en el futuro el kernel kernel8.img también se vuelve de 16KB?
Muy improbable, porque ese nombre está reservado tradicionalmente para el kernel de 4KB. En todo caso, si ocurriera, existiría otra forma de forzar 4KB. Pero de momento no hay indicios.

Me pasa en Ubuntu Server o Arch Linux ARM, ¿vale lo mismo?
El problema puede aparecer en cualquier distribución que haya adoptado el kernel de 16KB para la Pi 5. La solución es similar: busca cómo cargar un kernel con páginas de 4KB. En algunos casos puedes instalar el kernel raspberrypi-kernel o compilar el tuyo. Pero para no complicarte, te recomiendo probar primero con la línea kernel=kernel8.img en el config.txt. Suerte.

¿Por qué no me pasaba en Debian 12?
Porque Debian 12 usaba el kernel clásico de 4KB. El cambio a 16KB ha llegado con las versiones más recientes (Debian 13, Trixie, y algunas actualizaciones de Raspberry Pi OS). Es un cambio silencioso que nos ha pillado a muchos por sorpresa.

La Bitácora de Pruebas: Descartando pieza a pieza

Estas son las pruebas que realicé para descartar problemas de hardware, en la que fui aislando cada componente del sistema, empezando por lo mas básico:

1. El test de estrés a la Memoria RAM (memtester)

En los casos de corrupción aleatoria de datos, el primer sospechoso siempre es un módulo de memoria defectuoso. Instalamos la herramienta memtester para exprimir la RAM de las Pi 5 y obligarlas a leer y escribir patrones de datos buscando bits defectuosos.

sudo apt install memtester
sudo memtester 4000M 3

Le asignamos 4GB de RAM y le pedimos 3 pasadas completas.

Resultado: No debe de dar errores.

2. Auditoría y estrés del NVMe local (Descarte de almacenamiento)

Descartada la RAM, el siguiente sospechoso era el almacenamiento. ¿Estaba el bus PCIe, el adaptador HAT oficial o el propio firmware del NVMe corrompiendo los datos al escribir? Para salir de dudas, sometimos el disco a una auditoría en tres fases: pasiva, de superficie y de hash lógico.

Fase A: Lectura de salud S.M.A.R.T.

Instalamos las herramientas de diagnóstico para interrogar directamente al firmware del disco y comprobar si arrastraba fallos físicos o sectores reasignados:

sudo apt install smartmontools
sudo smartctl -a /dev/nvme0n1

(Nota: Cambia /dev/nvme0n1 por la ruta específica de tu dispositivo si varía).

Resultado: Todo limpio. Parámetros críticos como Media and Data Integrity Errors o sectores reasignados estaban a cero. El disco reportaba salud de fábrica.

Fase B: Test de superficie a bajo nivel (badblocks)

Para asegurar que ninguna celda de silicio flaqueaba bajo estrés, ejecutamos la prueba de fuego más exhaustiva que existe en Linux:

sudo badblocks -vsw -b 4096 /dev/nvme0n1

⚠️ ¡Ojo! El parámetro -w realiza un test de escritura destructivo (escribe patrones encima de lo que haya). Hazlo siempre sobre un disco vacío o antes de montar datos definitivos.

Este comando realiza 4 pasadas completas a todo el disco, escribiendo, leyendo y verificando secuencialmente patrones de bits totalmente diferentes (0xaa, 0x55, 0xff y 0x00). Si un bit se queda pegado o falla al retener la información, badblocks lo caza al vuelo.

Resultado: Cero errores en las 4 comprobaciones. Las celdas físicas del NVMe respondieron de forma impecable.

Fase C: Integridad lógica y velocidad en ráfaga (dd + sha256sum)

Por último, queríamos estresar el bus PCIe de la Raspberry Pi 5 a su máxima tasa de transferencia y comprobar si los archivos se «deformaban» al copiarse localmente. Ejecutamos esta secuencia en bloque:

# 1. Creamos un archivo masivo de 1 GB de ceros puros a máxima velocidad
dd if=/dev/zero of=test_gordo.img bs=1M count=1024

# 2. Calculamos su huella digital o hash único original
sha256sum test_gordo.img

# 3. Lo duplicamos a otra zona física del NVMe
cp test_gordo.img test_gordo_copia.img

# 4. Calculamos el hash de la copia para comprobar si ha mutado
sha256sum test_gordo_copia.img

Resultado: Los hashes de ambos archivos coincidieron al milímetro, firmando un resultado idéntico. Además, la transferencia local se mantuvo a una velocidad brutal de 1,8 GB/s.

Conclusión del descarte de hardware

Si el bus PCIe, las pistas del HAT o el controlador del disco sufrieran la más mínima degradación por temperatura o carga, los hashes habrían salido distintos y el test de bloques habría cantado fallos.

Con la RAM en perfecto estado y el almacenamiento local rindiendo como una roca a casi 2 GB/s, el hardware quedaba totalmente absuelto. El poltergeist de la corrupción de datos tenía que ser, por fuerza, un problema de software entre el Kernel y la pila de red.

3. La prueba cruzada de red

Si las tripas de la máquina estaban sanas, miramos hacia afuera. Repetimos las descargas en mi segunda Raspberry Pi 5. Mismo resultado: hashes aleatorios. En cambio, al realizar la misma descarga en un PC Intel conectado por Ethernet en el mismo switch, los hashes salían perfectos a la primera. El problema se concentraba exclusivamente en las Pi 5.

4. El misterio de la EEPROM

Para asegurar que no arrastrábamos configuraciones antiguas grabadas a fuego en las placas, entramos en sudo raspi-config y restablecimos el Bootloader (EEPROM) a los valores por defecto de fábrica. El problema persistió.

5. La prueba del Wi-Fi

Para confirmar si el fallo venía exclusivamente por el cable eléctrico, desconectamos el cable Ethernet y activamos el Wi-Fi. Al ir por un chip inalámbrico independiente, la corrupción desapareció, confirmando que la interfaz por cable eth0 era el embudo donde se deformaban los paquetes.

Conclusión:

Me costó semanas de pruebas, foros y cabezazos contra el techo. Al final, el culpable no era ni el hardware ni la red: era un cambio interno en el kernel que nadie me había advertido.

Si esta entrada te ha salvado de un dolor de cabeza, por favor, compártela en los foros, en los grupos de Telegram, en Reddit o con ese amigo que tiene una Raspberry Pi 5 y se queja de que «las descargas le van mal». Entre todos podemos hacer que Linux sea más predecible y amigable.

Y recuerda: cuando todo falle, prueba a poner kernel=kernel8.img en el config.txt. A veces la solución más pequeña es la que desatasca el mayor de los problemas.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio