
8BitDo Retro Keyboard en Linux: firmware, Super Buttons y el secreto de XKB (Arch/CachyOS)
El 8BitDo Retro Mechanical Keyboard es una delicia para los amantes de la estética de 8 bits (versiones NES, Famicom y Commodore). Pero más allá de los interruptores mecánicos y los potenciómetros retro para el volumen, su mayor atractivo son los Super Buttons: dos botones gigantes programables (Rojo A y Rojo B) que se conectan mediante jacks traseros de 3.5 mm.

Sin embargo, para los usuarios de Linux hay una barrera inmediata: el software oficial (8BitDo Ultimate Software V2) solo existe para Windows. Si usas Arch Linux, CachyOS, Fedora o Debian, en la caja parece que estás condenado a quedarte con las macros por defecto o arrancar una máquina virtual solo para cambiar dos teclas.
Peor aún: cuando logras mapear teclas extendidas como F13 o F14, te encuentras con que GNOME Wayland parece ignorarlas por completo.
Tras investigar el protocolo USB a bajo nivel, la memoria EEPROM del teclado y las entrañas de XKB en Linux, aquí tienes la guía definitiva para configurar, reprogramar y exprimir este teclado en Linux como un profesional.
1. Arquitectura de Hardware y Protocolo HID
Para entender cómo funciona el teclado en Linux, primero hay que mirar lo que reporta el bus USB (lsusb muestra Vendor ID 0x2dc8 y Product ID 0x5200):
$ ls -l /dev/input/by-id/usb-8BitDo*
... usb-8BitDo_8BitDo_Retro_Keyboard-event-mouse -> ../event29
... usb-8BitDo_8BitDo_Retro_Keyboard-if01-event-kbd -> ../event30
... usb-8BitDo_8BitDo_Retro_Keyboard-if02-hidraw -> ../../hidraw11
El teclado expone tres interfaces USB HID independientes:
- Interface 0 (
event29/hidraw9): Emulación de puntero y controles de ratón. - Interface 1 (
event30/hidraw10): Teclado estándar. Utiliza un descriptor híbrido con reportes estándar 6KRO (ID 1) y mapas de bits NKRO completos (IDs 10 y 12). - Interface 2 (
hidraw11): Canal propietario de control y programación. Acepta reportes OUT (ID 82) e IN (ID 84) para leer y escribir directamente en la memoria no volátil (EEPROM) del microcontrolador.
[!IMPORTANT] Regla de oro de conectividad: El canal propietario de flasheo (Interface 2) sólo está disponible cuando el teclado se conecta mediante cable USB-C. Ni el receptor inalámbrico de 2.4 GHz ni el enlace Bluetooth exponen esta interfaz de desarrollo. Una vez programado el perfil por cable, los mapeos quedan grabados en hardware y se emiten de forma idéntica por Bluetooth y 2.4G.
Arquitectura de Conexión y Super Buttons
┌────────────────────────────────────────────────────────────────────────┐
│ 8BitDo Retro Mechanical Keyboard │
│ │
│ [ OFF/BT/2.4G ] [ Volumen ] [ ⭐ Mapeo ] [ ♥ Perfil ] │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Teclado 87 Teclas │ │
│ │ (Switches Kailh Box White V2) │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ [ C1 ] [ C2 ] [ C3 ] [ C4 ] │
└──────────┬───────────────────┬───────────────────┬───────────────────┬─┘
│ (Jack 3.5mm) │ │ │
▼
┌───────────────────┐
│ Super Buttons │
│ ┌───┐ ┌───┐ │
│ │ A │ │ B │ │ (Hasta 4 parejas externas = 8 botones totales)
│ └───┘ └───┘ │
└───────────────────┘
Detrás del teclado hay 4 conectores jack estéreo (etiquetados C1, C2, C3, C4). Internamente, cada jack tiene dos líneas (a y b), lo que da 8 puertos lógicos:
- Bloque izquierdo (Rojo A):
external-aa,external-ba,external-xa,external-ya. - Bloque derecho (Rojo B):
external-ab,external-bb,external-xb,external-yb.
┌──► Interface 0: Ratón (/dev/input/event29)
│
Cable USB-C ├──► Interface 1: Teclado NKRO (/dev/input/event30)
Teclado ────► PC Linux ─┤
└──► Interface 2: Flasheo EEPROM (/dev/hidraw11)
├── Reporte OUT (0x52): Escritura de perfiles
└── Reporte IN (0x54): Lectura y estado
2. Ecosistema en Linux: eightkbdctl vs 8bdkbd
Para comunicarnos con la Interface 2 desde Linux sin recurrir a máquinas virtuales con Windows existen dos proyectos destacados de ingeniería inversa en la comunidad:
eightkbdctl(de paulguy, en github.com/paulguy/8-retro-kbd-ctl): Biblioteca y CLI en Python que interactúa a bajo nivel directamente con el nodo/dev/hidrawdel kernel. Permite leer y escribir perfiles en la EEPROM, programar macros complejas de múltiples pulsaciones y gestionar todos los puertos externos de los Super Buttons. Es la herramienta que utilizaremos en esta guía.8bdkbd(de goncalor, en github.com/goncalor/8bitdo-kbd-mapper): Implementación alternativa con una CLI muy limpia y declarativa (8bdkbd map capslock esc), documentación detallada de paquetes enprotocol.txty soporte tanto para el modelo Retro 87 como para el Retro 108.
Frente a Frente: ¿Cuál elegir?
A la hora de elegir una herramienta para nuestro setup, hay diferencias arquitectónicas críticas:
| Característica | eightkbdctl (paulguy) | 8bdkbd (goncalor) |
|---|---|---|
| Capa de transporte USB | /dev/hidraw nativo del kernel | pyusb / libusb directo |
| Impacto en el sistema | Limpio e inocuo: No altera los drivers del kernel. | Invasivo: Requiere desvincular el driver del kernel (echo $kernel > usbhid/unbind) mediante reglas udev. |
| Super Buttons externos (Jacks 3.5mm) | Soportados al 100% (external-aa a external-yb) | ❌ No soportados (marcado como pendiente en su TODO) |
| Macros complejas con retardo | Soportadas al 100% (secuencias temporizadas) | ❌ No soportadas (solo mapeos 1:1) |
| Teclados soportados | Retro 87 (TKL) | Retro 87 y Retro 108 (Full size) |
| Documentación del protocolo | Ninguna (código directo) | Excelente (protocol.txt) con capturas de paquetes byte a byte |
| Ergonomía de CLI | Estilo bajo nivel / interactivo | Muy intuitiva y declarativa (status, profile, map) |
[ eightkbdctl ] [ 8bdkbd ]
│ │
▼ ▼
Acceso por /dev/hidraw11 Acceso por pyusb / libusb
│ │
▼ ▼
Llamadas ioctl Desvincula driver del kernel
(Inocuo para el kernel) (echo $kernel > usbhid/unbind)
│ │
└─────────────────┬─────────────────┘
▼
[ USB HID Interface 2 (0x52 / 0x54) ]
▼
[ Memoria EEPROM 8BitDo ]
El curioso caso de las teclas F13 a F24
Durante el desarrollo de 8bdkbd, el análisis de capturas de paquetes USB (pcap) del software oficial de Windows reveló algo llamativo: el software propietario de 8BitDo no utiliza los códigos estándar de la especificación HID Usage Tables (donde F13 es 0x68 y F14 es 0x69), sino un rango desplazado no estándar (0x070076 para F13, 0x070077 para F14).
Sin embargo, el microcontrolador del teclado acepta ambos: cuando eightkbdctl le envía el código estándar 0x69 de F14, el firmware lo graba correctamente en la EEPROM y emite KEY_F14 al kernel de Linux.
El veredicto
Para nuestro objetivo —exprimir los Super Buttons gigantes y vincularlos a acciones avanzadas— eightkbdctl es la opción ganadora: soporta los 8 puertos jack traseros de serie y no requiere romper el enlace del driver usbhid del kernel.
Dependencias del Sistema
En Arch Linux o CachyOS instalamos las herramientas del sistema y los paquetes de OCR (si queremos usar el botón para extraer texto):
sudo pacman -S python python-virtualenv tesseract tesseract-data-spa tesseract-data-eng wl-clipboard
Regla udev opcional (para ejecutar sin sudo)
Por defecto, los dispositivos /dev/hidraw* pertenecen al grupo root. Si prefieres interactuar con el teclado con tu usuario habitual:
echo 'SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2dc8", ATTRS{idProduct}=="5200", TAG+="uaccess"' | sudo tee /etc/udev/rules.d/99-8bitdo-retro.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
Preparación del Entorno Virtual (eightkbdctl)
Para no ensuciar el entorno global de Python, aislamos las librerías necesarias:
mkdir -p ~/dev/tools && cd ~/dev/tools
git clone https://github.com/paulguy/8-retro-kbd-ctl.git
cd 8-retro-kbd-ctl
python -m venv ~/dev/tools/8retro-venv
~/dev/tools/8retro-venv/bin/pip install pyudev ioctl-opt xdg-base-dirs
3. Reprogramación del Firmware sin Windows
Con el teclado conectado por cable USB, invocamos eightkbdctl con privilegios sobre el nodo hidraw:
cd ~/dev/tools/8-retro-kbd-ctl/src
PY=~/dev/tools/8retro-venv/bin/python
# 1. Inspeccionar el perfil actual
sudo $PY -m eightkbdctl.eightkbdctl get-profile
# 2. Asignar nombre al perfil (¡CRÍTICO!)
sudo $PY -m eightkbdctl.eightkbdctl set-name pablo
El Quirk del “Nombre Vacío”
El firmware del 8BitDo tiene una peculiaridad documentada: si el nombre del perfil se deja vacío (""), el firmware inhabilita automáticamente el botón de perfil, haciendo que los mapeos dejen de funcionar. Asignar siempre un nombre (set-name pablo) garantiza que el perfil permanezca activo.
Mapeando los Super Buttons
En nuestro flujo de trabajo, queremos:
- Botón Rojo A (Izquierdo): Mapeado a
f14para OCR de pantalla. - Botón Rojo B (Derecho): Mapeado a
print-screenpara captura de pantalla directa instantánea.
Ejecutamos el mapeo de todos los puertos correspondientes:
# Puertos izquierdos -> F14
for B in aa ba xa ya; do
sudo $PY -m eightkbdctl.eightkbdctl set-key external-$B f14
done
# Puertos derechos -> PrintScreen
for B in ab bb xb yb; do
sudo $PY -m eightkbdctl.eightkbdctl set-key external-$B print-screen
done
Podemos comprobar que los cambios quedaron grabados en la EEPROM:
sudo $PY -m eightkbdctl.eightkbdctl get-profile | grep -E 'external|Profile'
4. El Gran Misterio de XKB: ¿Por qué F14 no respondía en GNOME?
Aquí es donde el 99% de los usuarios se quedan atascados.
Mapeas el botón a f14. Abres la configuración de GNOME o de una extensión y asignas el atajo ['F14']. Pulsas el botón rojo… y no ocurre absolutamente nada.
¿El teclado está roto? ¿El firmware no emite? No. El hardware emite perfectamente el código HID 0x69 (KEY_F14 / código Linux 184).
El problema está en el mapa de símbolos por defecto de Linux: /usr/share/X11/xkb/symbols/inet.
Si inspeccionamos las definiciones de XKB para teclas de función extendidas:
// /usr/share/X11/xkb/symbols/inet
key <FK13> { [ XF86Tools ] };
key <FK14> { [ XF86Launch5 ] };
key <FK15> { [ XF86Launch6 ] };
¡Boom! En Linux, la tecla física KEY_F14 no produce el keysym F14, sino XF86Launch5 (y KEY_F13 produce XF86Tools).
Mutter (el gestor de ventanas de GNOME) recibe la pulsación del hardware, busca en la tabla de símbolos de XKB y obtiene XF86Launch5. Como tú le dijiste que escuchara F14, la señal se descartaba silenciosamente.
[ Pulsación física Botón Rojo A ]
│
▼ (Jack 3.5 mm C1)
[ Microcontrolador 8BitDo ]
│
▼ (USB / BT HID Report: Usage 0x69)
[ Kernel Linux (evdev) ] ────────► Emite evento KEY_F14 (código 184)
│
▼ (/usr/share/X11/xkb/symbols/inet)
[ Capa XKB en Linux ] ────────► Traduce KEY_F14 a: XF86Launch5
│
▼ (Wayland compositor)
[ Mutter / GNOME Shell ] ────────► Intercepta atajo 'XF86Launch5'
│
▼ (Extensión ocr-to-clipboard)
[ Tesseract OCR + wl-copy ] ─────► Extrae texto directo al portapapeles
5. Integración con GNOME Wayland
Ahora que conocemos los keysyms reales, configuramos el entorno para sacarle el máximo partido:
1. Botón Rojo B: Captura Instantánea (Solo Pantalla Principal)
Para que la tecla Print guarde directamente una captura a ~/Imágenes/Capturas de pantalla sin abrir diálogos emergentes:
# Captura de pantalla directa automática
gsettings set org.gnome.shell.keybindings screenshot "['Print', '<Shift>Print']"
# Diálogo interactivo de captura (con Ctrl+Print)
gsettings set org.gnome.shell.keybindings show-screenshot-ui "['<Ctrl>Print']"
El truco multimonitor: Capturar solo la Pantalla Principal
En escritorios con varios monitores (como una pantalla ultrapanorámica combinada con un monitor secundario vertical), la captura nativa de GNOME genera una imagen gigante uniendo todos los monitores (por ejemplo, 6560x1440 px con una Samsung Odyssey G9 49" a 5120x1440 más un monitor vertical 27").
Para que el Botón Rojo B capture únicamente la pantalla principal sin perder la inmediatez ni requerir diálogos interactivos de Wayland, creamos un servicio de usuario (~/.config/systemd/user/auto-crop-primary-screenshot.service):
- Utiliza
Gio.FileMonitorpara detectar en milisegundos cuándo GNOME escribe el archivo en~/Imágenes/Capturas de pantalla. - Consulta a Mutter vía D-Bus (
org.gnome.Mutter.DisplayConfig) la posición y resolución del monitor principal en tiempo real. - Si la imagen abarca múltiples pantallas, la recorta limpiamente a la pantalla principal y sincroniza el portapapeles con
wl-copy. Si se trabaja con un único monitor, no altera el archivo.
2. Botón Rojo A: OCR de Pantalla al Portapapeles
Instalamos y habilitamos la extensión nativa Native Screenshot UI OCR Extended (ocr-to-clipboard@oreocapybara).
Registrar y compilar el esquema en el usuario
Para que gsettings reconozca el esquema de la extensión:
ln -sf ~/.local/share/gnome-shell/extensions/ocr-to-clipboard@oreocapybara/schemas/org.gnome.shell.extensions.ocr-to-clipboard.gschema.xml ~/.local/share/glib-2.0/schemas/
glib-compile-schemas ~/.local/share/glib-2.0/schemas/
Asignar el atajo con el keysym real (XF86Launch5)
Configuramos la extensión con soporte para el keysym XKB y el atajo tradicional de teclado:
gsettings set org.gnome.shell.extensions.ocr-to-clipboard capture-ocr-shortcut "['XF86Launch5', 'F14', 'XF86Tools', 'F13', '<Super><Shift>o']"
Y recargamos la extensión:
gnome-extensions disable ocr-to-clipboard@oreocapybara
sleep 0.5
gnome-extensions enable ocr-to-clipboard@oreocapybara
Ahora, al golpear el Botón Rojo A, GNOME abre inmediatamente el visor de recorte: seleccionas cualquier texto en pantalla (un PDF protegido, una imagen, un vídeo) y Tesseract extrae el texto directo a tu portapapeles mediante wl-copy.
6. Ideas de la Comunidad: ¿Para qué usar los Super Buttons?
Más allá de nuestro setup enfocado en OCR y captura instantánea, la comunidad en Reddit (r/8bitdo, r/MechanicalKeyboards) y foros de desarrollo comparte usos creativos para estos enormes pulsadores:
- El botón de “Deploy / Push”: Disparar un
git pushcon orgullo tras terminar una tarea, o lanzar una batería de pruebas (pytest,cargo test,npm test) con un puñetazo al botón rojo. - Vim / Neovim enfático: Mapear un botón a
<Esc>para salir de modo inserción al instante, o al comando:w<CR>para guardar cambios con contundencia. - Enviar email con dramatismo (
Ctrl + Enter): Uno de los usos más votados. Pulsar el botón gigante para enviar un correo importante o un mensaje en Slack/Discord. - El botón de pánico / Boss Key (
Super + L): Bloquear la sesión al levantarte del escritorio o si alguien se acerca a tu puesto. - Mute de micrófono / Push-To-Talk: Silenciar micro global en Discord, Zoom o Google Meet en plena llamada.
- Gaming retro (RetroArch / MAME): Guardar estado (Quick Save) en el botón A y cargar estado (Quick Load) en el botón B.
- Modding DIY (Pedales de pie y botones arcade): Los puertos jack traseros de 3.5 mm no llevan audio; son contactos secos de bajo voltaje (cierran circuito). Varios usuarios conectan pedales de pie comerciales (de guitarra o de costura) para usarlos en el suelo como freno de mano en simuladores o para agacharse (crouch) en shooters sin despegar los dedos del teclado.
7. Lista de Verificación y Troubleshooting
- El Botón del Corazón (Profile LED):
- El teclado cuenta con un botón dedicado con un corazón iluminado con un LED blanco.
- El LED debe estar ENCENDIDO. Si se pulsa accidentalmente y se apaga, el teclado vuelve al perfil de fábrica (en el que los puertos externos están inhabilitados por defecto) y los Super Buttons no emitirán tus teclas personalizadas.
- Bug de visualización en
eightkbd.py:- En la línea 555 de
eightkbd.py, un slice erróneo (data_return[1][NAME_HDR.size:]) hace queget-profilemuestreProfile Name:en blanco en la terminal. No te preocupes: el nombre sí está grabado en el hardware; es solo un bug cosmético del script lector.
- En la línea 555 de
- Diagnóstico de teclas en tiempo real:
- Si quieres ver exactamente qué código llega al kernel al pulsar cualquier tecla:Verás
sudo evtest /dev/input/by-id/usb-8BitDo_8BitDo_Retro_Keyboard-if01-event-kbdKEY_F14(código 184) para el botón izquierdo yKEY_SYSRQ(código 99) para el derecho.
- Si quieres ver exactamente qué código llega al kernel al pulsar cualquier tecla:
Con este flujo de trabajo, el 8BitDo Retro Mechanical Keyboard se convierte en un centro de productividad absoluto en Linux, sin depender en ningún momento de Windows.