• Saltar al contenido principal
  • Saltar a la barra lateral principal
  • Blog
  • Sistemas Operativos
    • Todos los sistemas operativos del Raspberry Pi Imager en 2026
  • Tipos de Raspberry Pi
    • Selector interactivo de Raspberry Pi
    • Raspberry Pi: rivales y alternativas SBC en 2026 con Armbian y DietPi
  • Glosario
  • FAQ
  • Contacto
  • Cookies y RGPD
  • Acerca de

Raspberry para torpes

Blog sobre Raspberry Pi en español desde 2013. Guías de configuración, hardware, sistemas operativos y proyectos para todos los niveles.

odroid-u3 kernel 6.12

ODROID-U3 con kernel 6.12 usando los kernels de Velvet OS

16 abril, 2026 by manuti Deja un comentario

☕
¿El blog te ha sido útil?Puedes invitarme a un café en Ko-fi. Sin suscripciones, sin compromisos.
Invitar a un café

La ODROID-U3 es de 2013. Quad-core Exynos4412 a 1,7GHz, 2GB de RAM y almacenamiento en eMMC. Hace más de una década que Hardkernel la discontinuó, pero sigue funcionando. El problema es que el kernel oficial que traía —un 3.8 parcheado— se quedó fósil. Si tienes una corriendo Ubuntu 22.04 con un kernel 4.16 compilado a mano hace años, tarde o temprano te planteas actualizarlo. Este servidor es uno de los que más uso, pero siempre estoy dudando entre dejarlo ya hasta que la placa falle o tener algo más nuevo.

Cuando descubrí la existencia de VelvetOS, pensé en actualizar todo, pero me daba pereza y además había dudas de que funcionase en la memoria interna eMMC que es mucho más rápida que usar una microSD. Así que hice un intento con un kernel 6.8 genérico de Ubuntu, compilado con ayuda de Claude Code, que no arrancó. Pantalla negra, sin SSH, sin nada. Lo que sigue es lo que aprendí en el proceso y la solución que finalmente funcionó.

odroid-u3 kernel 4.16

El U-Boot es el punto de partida

Antes de pensar en el kernel hay que saber qué versión de U-Boot tienes instalada. El U-Boot original que venía con la ODROID-U3 era de 2010 y solo entiende el comando bootm, que requiere imágenes en formato uImage con cabecera mkimage y tiene un límite de tamaño que un kernel moderno supera sin despeinarse.

Si en algún momento actualizaste el U-Boot desde el foro de Hardkernel y esta web que aún sigue viva —como es mi caso—, o si instalaste una imagen de Velvet OS o similar, lo más probable es que tengas algo mucho más reciente. Puedes comprobarlo desde el sistema arrancado:

sudo strings /dev/mmcblk1boot0 | grep -iE "U-Boot 20[0-9]{2}"

En mi caso el resultado fue U-Boot 2020.10. Con eso ya puedes arrancar kernels modernos usando bootz y DTB separado. Si tienes algo anterior a 2015, necesitarás actualizar el U-Boot antes de continuar. Eso es otra historia que no cubro aquí, pero que se puede intentar con esta web: Odroid U3 Kernel Upgrade + Docker

El dispositivo eMMC puede aparecer como mmcblk0 o mmcblk1 según la placa. Comprueba cuál es el tuyo con lsblk antes de ejecutar el comando. En mi caso tengo memoria eMMC (mmcblk0), una microSD (mmcblk2) y un pendrive por USB (sda).

lsblk

Por qué no funcionó el kernel genérico de Ubuntu

El kernel 6.8 genérico de Ubuntu es enorme y está compilado para todo el hardware ARM posible. Eso ya es un problema de tamaño. Pero el problema real son los patches. El Exynos4412 necesita al menos tres correcciones que no están en el árbol genérico:

Primero, un parche que arregla el USB en el Exynos4412 (fix-odroid-x2-usb.patch). Segundo, un parche para el HDMI (exynos-hdmi-infoframes-patch). Tercero, soporte para MAC fija en la interfaz de red, que en esta placa va por USB interno con el chip smsc95xx. Sin ese módulo en el initrd, el sistema arranca pero sin red. Sin red, no hay SSH y parece que no ha arrancado cuando en realidad sí lo ha hecho.

De hecho, el primer síntoma que ves es ese: pantalla negra —normal, el driver Mali no funciona en mainline sin más trabajo— y sin SSH. Lo segundo tiene arreglo fácil si sabes que es el módulo de red. Lo primero requiere un kernel compilado con los patches correctos.

La solución: el kernel precompilado de Velvet OS

hexdump0815 es el desarrollador detrás de Velvet OS, un framework para construir imágenes Debian arrancables en hardware ARM antiguo. Entre sus repositorios hay uno con kernels precompilados para el Exynos4412, probados en la ODROID-U3. El sufijo stb-exy+ identifica estos builds.

En febrero de 2025 publicó el 6.12.12-stb-exy+, probado en ODROID-U3+. Incluye los tres patches mencionados, un DTB correcto y un initrd propio de unos 18MB —frente a los 56MB del genérico de Ubuntu. Es exactamente lo que necesitamos.

Descarga el paquete en tu PC:

wget https://github.com/hexdump0815/linux-mainline-and-mali-generic-stable-kernel/releases/download/6.12.12-stb-exy%2B/6.12.12-stb-exy+.tar.gz

Súbelo a la ODROID por SCP si estás conectado por SSH desde un PC con Linux y extráelo luego en la odroid:

scp 6.12.12-stb-exy+.tar.gz usuario@ip-odroid:~/
ssh usuario@ip-odroid
tar xzf 6.12.12-stb-exy+.tar.gz

Instalar el kernel

Esto es como un transplante de cerebro. Copia el kernel y el DTB a la partición de arranque. La partición FAT está montada en /media/boot en las instalaciones habituales de la ODROID-U3:

sudo cp ~/boot/zImage-6.12.12-stb-exy+ /media/boot/zImage_6.12
sudo cp ~/boot/dtb-6.12.12-stb-exy+/exynos4412-odroidu3.dtb /media/boot/exynos4412-odroidu3_6.12.dtb

Instala los módulos en el sistema:

sudo cp -r ~/lib/modules/6.12.12-stb-exy+ /lib/modules/

Genera el uInitrd que necesita el U-Boot a partir del initrd incluido en el paquete:

sudo mkimage -A arm -O linux -T ramdisk -a 0x0 -e 0x0 \
  -n "initrd-6.12" \
  -d ~/boot/initrd.img-6.12.12-stb-exy+ \
  /media/boot/uInitrd-6.12.12-stb-exy+
odroid-u3 eMMC

Configurar el arranque

Con U-Boot 2020.x el arranque se puede configurar con boot.ini y boot.scr. El U-Boot lee primero el boot.scr, así que hay que generar ambos. Primero el boot.ini:

sudo tee /media/boot/boot.ini.6.12 << 'EOF'
ODROID4412-UBOOT-CONFIG

setenv initrd_high "0xffffffff"
setenv fdt_high "0xffffffff"

setenv bootcmd "fatload mmc 0:1 0x40008000 zImage_6.12; fatload mmc 0:1 0x48000000 exynos4412-odroidu3_6.12.dtb; fatload mmc 0:1 0x49000000 uInitrd-6.12.12-stb-exy+; bootz 0x40008000 0x49000000 0x48000000"

setenv bootargs "console=tty1 console=ttySAC1,115200n8 root=UUID=TU-UUID-AQUI rootwait ro mem=2047M"

boot
EOF

Sustituye TU-UUID-AQUI por el UUID real de tu partición raíz, que puedes obtener con sudo blkid. Ahora el boot.scr:

cat << 'EOF' > /tmp/boot.txt.6.12
setenv initrd_high "0xffffffff"
setenv fdt_high "0xffffffff"
setenv bootcmd "fatload mmc 0:1 0x40008000 zImage_6.12; fatload mmc 0:1 0x48000000 exynos4412-odroidu3_6.12.dtb; fatload mmc 0:1 0x49000000 uInitrd-6.12.12-stb-exy+; bootz 0x40008000 0x49000000 0x48000000"
setenv bootargs "console=tty1 console=ttySAC1,115200n8 root=UUID=TU-UUID-AQUI rootwait ro mem=2047M"
boot
EOF

sudo mkimage -C none -A arm -T script -d /tmp/boot.txt.6.12 /media/boot/boot.scr.6.12

Antes de activar el nuevo arranque, guarda una copia de seguridad de los ficheros actuales:

sudo cp /media/boot/boot.ini /media/boot/boot.ini.anterior
sudo cp /media/boot/boot.scr /media/boot/boot.scr.anterior

Ahora activa el nuevo arranque y reinicia:

sudo cp /media/boot/boot.ini.6.12 /media/boot/boot.ini
sudo cp /media/boot/boot.scr.6.12 /media/boot/boot.scr
sudo reboot

Verificar que funciona

Espera dos o tres minutos y conéctate por SSH. Si todo ha ido bien:

uname -a
# Linux odroid 6.12.12-stb-exy+ #1 SMP PREEMPT ... armv7l armv7l armv7l GNU/Linux

Si no responde SSH, monta la eMMC en otro equipo y restaura los ficheros de arranque anteriores desde las copias de seguridad.

odroid-u3 kernel 6.12

Un apunte sobre los kernels genéricos de apt

Si tienes Ubuntu instalado, apt intentará instalar y activar el kernel genérico en cada actualización. Ese kernel no arranca en la ODROID-U3. Conviene bloquearlo para evitar sorpresas:

sudo apt-mark hold linux-image-generic linux-headers-generic

El kernel de hexdump0815 hay que gestionarlo a mano: descargar la nueva versión cuando salga, repetir los pasos de instalación y actualizar los ficheros de arranque. No es cómodo, pero es lo que hay con hardware tan específico. Lo mismo hago el salto al nuevo kernel 7 por tener un número más redondo en algún momento.

El problema con flash-kernel

Si en algún momento instalaste un kernel genérico de Ubuntu —aunque fuera para probarlo— puede que también se instalara flash-kernel, un paquete que automatiza la copia del kernel y el DTB a la partición de arranque en hardware ARM. En la ODROID-U3 con el kernel de hexdump0815 ese paquete es completamente innecesario. Peor aún: puede entrar en un estado roto difícil de salir.

El error concreto que aparece es este:

Couldn't find DTB exynos4412-odroidu3.dtb on the following paths:
/etc/flash-kernel/dtbs /usr/lib/linux-image- /lib/firmware//device-tree/

La causa es que flash-kernel intenta buscar el DTB usando la versión del kernel genérico instalado por apt. Si ese kernel ya no está o la variable de versión queda vacía en el trigger, genera rutas inválidas. El resultado es un ciclo vicioso: falla al instalar y también al intentar purgar el kernel genérico.

La solución pasa por tres pasos. Primero, purgar el kernel genérico si aún está instalado:

sudo apt purge linux-image-6.8.0-107-generic linux-modules-6.8.0-107-generic

Si el error persiste y flash-kernel sigue roto, forzar su eliminación saltándose el script de postinst:

sudo dpkg --remove --force-remove-reinstreq flash-kernel

Por último, limpiar los paquetes huérfanos que arrastra:

sudo apt purge devio libiniparser1 mtd-utils

Eliminar flash-kernel no afecta al arranque. El kernel de hexdump0815 gestiona su propio boot mediante los ficheros de la partición FAT, sin necesitar ningún automatismo de apt.

Sobre las velocidades de acceso al almacenamiento en la Odroid-U3

Ya comenté que tenía conectadas a la Odroid-U3 la memoria eMMC (mmcblk0), una microSD (mmcblk2) y un pendrive por USB (sda). Para probar la velocidad he usado este comando:

sudo hdparm -t --direct /dev/el-disco-a-probar-según-su-nombre-visto-en-lsblk

Mide la velocidad de lectura del disco /dev/sda directamente desde el hardware, saltándose la caché del sistema operativo.

  • -t — mide el rendimiento de lectura secuencial en MB/s
  • --direct — usa O_DIRECT para evitar el buffer de caché del kernel, midiendo la velocidad real del disco sin que el sistema «ayude» con datos ya cacheados

El resultado típico tiene esta pinta:

Timing O_DIRECT disk reads: 234 MB in 3.01 seconds = 77.72 MB/s

Es una medida rápida y orientativa, no un benchmark exhaustivo. En mi caso sirve para ver que la memoria eMMC es mucho más rápida que la microSD o el pendrive por USB 2.0.

sudo hdparm -t --direct /dev/

La ODROID-U3 tiene más de diez años y sigue siendo una máquina capaz. Que alguien como hexdump0815 mantenga kernels actualizados y probados para ella es un trabajo que merece reconocimiento. Sin ese esfuerzo, esta placa llevaría años en el cajón.

Artículos relacionados:

  • linux-4-0
    Disponible el kernel de Linux 4.0 para Raspberry Pi
  • ODROID-XU3Lite-size
    Rivales Raspberry Pi: ODROID-XU3Lite
  • probando-ubuntu-raspberry-pi
    Probando Ubuntu Oficial en la Raspberry Pi
  • odroid-mc1-solo-cabecera
    Rivales Raspberry Pi: ODROID-MC1 Solo

Publicado en: Proyectos Etiquetado como: kernel, odroid

Barra lateral principal

α Fotografía El lado analógico de manuti

Categorías

  • Cajas (9)
  • comandos (21)
  • Compras (116)
  • dudas (41)
  • Empezando (55)
  • Hardware (109)
  • Instalacion (64)
  • Media Center (56)
  • Negocios (5)
  • Proyectos (45)
  • Rivales (114)
  • Sistemas Operativos (70)
  • sorteo (2)
Raspberry Pi 5 - 4GB RAM
Raspberry Pi 5 - 4GB RAM
Ver precio en Amazon →
Raspberry Pi Zero 2W
Raspberry Pi Zero 2W
Ver precio en Amazon →

Por si te lo perdiste

ubuntu ama a arm

Ubuntu apuesta fuerte por ARM: ya es arquitectura principal

NasberryPi

NasberryPi: NAS fácil con Raspberry Pi

github junio 2026

GitHub Raspberry Pi junio 2026: rpi-sb-provisioner

Raspberry Pi 5 - 8GB RAM
Raspberry Pi 5 - 8GB RAM
Ver precio en Amazon →

Visita la tienda Raspberry Pi en Amazon - enlace afiliado
© 2013–2026

Cookie y RGPD | Aviso Legal
Este sitio web usa cookies para mejorar su experiencia como usuario ► «Aceptar todo» Rechazar Elegir cookies ◘ Si necesita Política de cookies
Política de Cookies

Resumen de privacidad

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. De estas cookies, las clasificadas como necesarias se almacenan en tu navegador, ya que son esenciales para el funcionamiento de las funcionalidades básicas del sitio web. También utilizamos cookies de terceros que nos ayudan a analizar y entender cómo usas este sitio web. Estas cookies se almacenarán en tu navegador únicamente con tu consentimiento. También tienes la opción de rechazarlas. Sin embargo, rechazar algunas de estas cookies puede afectar a tu experiencia de navegación.
Necessary
Siempre activado
Las cookies necesarias son imprescindibles para el funcionamiento correcto del sitio web. Esta categoría solo incluye cookies que garantizan las funcionalidades básicas y las características de seguridad del sitio. Estas cookies no almacenan ninguna información personal.
CookieDuraciónDescripción
cookielawinfo-checkbox-advertisement1 añoEstablecida por el plugin GDPR Cookie Consent, esta cookie registra el consentimiento del usuario para las cookies de la categoría "Advertisement".
cookielawinfo-checkbox-analytics1 añoEstablecida por el plugin GDPR Cookie Consent, esta cookie registra el consentimiento del usuario para las cookies de la categoría "Analytics".
cookielawinfo-checkbox-comentarios1 añoEstablecida por el plugin GDPR Cookie Consent, esta cookie registra el consentimiento del usuario para las cookies de la categoría "Comentarios (Disqus)".
cookielawinfo-checkbox-functional1 añoEstablecida por el plugin GDPR Cookie Consent, esta cookie registra el consentimiento del usuario para las cookies de la categoría "Functional".
cookielawinfo-checkbox-necessary1 añoEstablecida por el plugin GDPR Cookie Consent, esta cookie registra el consentimiento del usuario para las cookies de la categoría "Necessary".
cookielawinfo-checkbox-others1 añoEstablecida por el plugin GDPR Cookie Consent, esta cookie almacena el consentimiento del usuario para las cookies de la categoría "Others".
cookielawinfo-checkbox-performance1 añoEstablecida por el plugin GDPR Cookie Consent, esta cookie almacena el consentimiento del usuario para las cookies de la categoría "Performance".
CookieLawInfoConsent1 añoCookieYes establece esta cookie para registrar el estado por defecto de los botones de cada categoría y el estado de la CCPA. Funciona únicamente en coordinación con la cookie principal.
wpEmojiSettingsSupportssesiónWordPress establece esta cookie cuando un usuario interactúa con emojis en un sitio WordPress. Ayuda a determinar si el navegador del usuario puede mostrar los emojis correctamente.
__cf_bm1 horaEsta cookie, establecida por Cloudflare, se utiliza para dar soporte a la gestión de bots de Cloudflare.
Functional
Las cookies funcionales ayudan a realizar ciertas funciones como compartir el contenido del sitio web en redes sociales, recoger comentarios y otras características de terceros.
CookieDuraciónDescripción
VISITOR_INFO1_LIVE6 mesesCookie establecida por YouTube para medir el ancho de banda y determinar si el usuario recibe la interfaz de reproductor nueva o antigua.
ytidb::LAST_RESULT_ENTRY_KEYnuncaYouTube utiliza esta cookie para almacenar la última entrada de resultados de búsqueda en la que hizo clic el usuario. Esta información se usa para mejorar la experiencia ofreciendo resultados más relevantes en el futuro.
Performance
Las cookies de rendimiento se utilizan para entender y analizar los índices clave de rendimiento del sitio web, lo que ayuda a ofrecer una mejor experiencia de usuario a los visitantes.
Analytics
Las cookies analíticas se utilizan para entender cómo interactúan los visitantes con el sitio web. Estas cookies ayudan a ofrecer información sobre métricas como el número de visitantes, la tasa de rebote, la fuente de tráfico, etc.
CookieDuraciónDescripción
YSCsesiónCookie establecida por YouTube que se usa para hacer seguimiento de las visualizaciones de vídeos embebidos en páginas de YouTube.
Advertisement
Las cookies de publicidad se utilizan para ofrecer a los visitantes anuncios y campañas de marketing relevantes. Estas cookies rastrean a los visitantes a través de distintos sitios web y recopilan información para mostrar anuncios personalizados.
CookieDuraciónDescripción
VISITOR_PRIVACY_METADATA6 mesesYouTube establece esta cookie para almacenar el estado de consentimiento de cookies del usuario para el dominio actual.
__Secure-ROLLOUT_TOKEN6 mesesYouTube utiliza esta cookie para gestionar el despliegue de funciones y la experimentación. Ayuda a Google a controlar qué funciones nuevas o cambios de interfaz se muestran a los usuarios como parte de pruebas y despliegues escalonados, garantizando una experiencia coherente durante un experimento.
__Secure-YECsesiónCookie de YouTube. Se encarga de almacenar tus preferencias de reproducción de video (como el volumen, la calidad de video predeterminada o la configuración de subtítulos) cuando ves videos de YouTube incrustados en otras páginas web.
__Secure-YNID6 mesesCookie de YouTube utilizada para proteger la seguridad del usuario y prevenir el fraude, especialmente durante el proceso de inicio de sesión.
Others
Otras cookies sin clasificar son aquellas que están siendo analizadas y que todavía no se han asignado a ninguna categoría.
Comentarios (Disqus)
Las cookies de comentarios permiten mostrar y gestionar el sistema de comentarios de terceros (Disqus), incluyendo el registro de usuarios y el control de spam. Estas cookies solo se cargan si aceptas esta categoría.
CookieDuraciónDescripción
disqus_unique1 añoCookie de Disqus usada para el registro de usuarios y control de spam en los comentarios.
GUARDAR Y ACEPTAR
Funciona con CookieYes Logo