Communitygithub.com

angelwzr/linux-phone-porting

Una skill de agente de codificación para ayudarte a portar Linux principal a un teléfono [Android?].

¿Qué es linux-phone-porting?

Esta skill está diseñada para asistentes de IA que trabajan en el port de Linux principal a teléfonos Android. Proporciona una metodología estricta y basada en evidencia para realizar portes de manera eficiente, reduciendo el costo de iteración de depuración (cada ciclo de compilación, flasheo e inicio toma de 5 a 10 minutos). La skill guía al usuario a través de cuatro fases: 1) configuración del puerto (respaldo de particiones críticas, establecimiento de la identidad del dispositivo y topología de arranque), 2) recopilación de evidencia del dispositivo en vivo (dmesg completo, pstore, ramoops, consola USB ACM), 3) investigación exhaustiva de seis familias de fuentes (mainline, kernel del proveedor, postmarketOS, Halium, Mobian, NixOS), y 4) implementación basada en esa evidencia. Incluye reglas clave como verificar siempre lo que realmente se ha flasheado, evitar que la lectura de interfaces de depuración fabrique síntomas, y clasificar los rechazos de firmware. Es adecuada para plataformas como Claude Code y otros asistentes de codificación, y asume que el bootloader del dispositivo ya está desbloqueado (no proporciona pasos para desbloquearlo).

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add angelwzr/linux-phone-porting

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Port de Linux a Teléfonos

En un teléfono en proceso de port de Linux principal, una iteración de depuración cuesta una compilación más un flasheo más un arranque (5-10 minutos), y las correcciones a ciegas se refutan con mucha más frecuencia de la que aciertan. Sigue este orden estrictamente.

0. Configurar el puerto

Haz esto una vez, antes del primer flasheo. Dos cosas hacen que esta sea la fase 0 en lugar de un trámite: el sistema de fábrica es la fuente de investigación de máxima autoridad que jamás tendrás para esta placa, y partes de él dejan de ser legibles en el momento en que comienzas a sobrescribir particiones.

Establece el objetivo primero, porque cada respuesta posterior depende de ello:

  • Identidad exacta del dispositivo — nombre comercial, nombre en clave, SoC, y la variante regional o de almacenamiento. Las variantes hermanas del mismo nombre comercial difieren rutinariamente en panel, controlador táctil o módem, y una corrección investigada contra la variante incorrecta parece plausible y falla.
  • Distribución e init objetivo — postmarketOS, Mobian, NixOS, Debian simple, u otra cosa. Esto decide el empaquetado, el diseño de la imagen, y cuál de las fuentes de la fase 2 es la más cercana.
  • Topología de arranque — A/B o no A/B, diseño de ranuras, y estado de bloqueo del bootloader. Solo bootloaders desbloqueados. Si el bootloader está bloqueado, detente: esta skill no desbloquea bootloaders ni proporciona pasos para hacerlo — dirige al usuario a las instrucciones de su propio OEM y reanuda una vez que el dispositivo esté desbloqueado.
  • Recuperación — si hay instalada una recuperación personalizada. No es un requisito: es una conveniencia para hacer copias de seguridad y restaurar.

Luego, haz una copia de seguridad completa de cada partición excepto userdata:

  • Omite userdata: ocupa la mayor parte del espacio, son los datos del usuario, y es la única partición que puedes permitirte perder.
  • Haz una copia de seguridad de las particiones únicas del dispositivo y nunca las publiques. La NV/EFS del módem, persist, y sus hermanas de calibración contienen el IMEI, la calibración de radio, y el ajuste de sensores para este teléfono individual. No son reproducibles a partir de ninguna imagen en internet, y un puerto que las corrompa deja un teléfono que no puede registrarse en una red. Trátalas como tanto críticas como privadas.
  • Calcula el hash de cada imagen y registra los hashes junto con la tabla de particiones. Más tarde necesitarás responder "¿lo que está en el dispositivo sigue siendo lo que respaldé?", y solo un hash lo responde.
  • Verifica que la copia de seguridad sea realmente restaurable antes del primer flasheo arriesgado, no después.

Lo que vale la copia de seguridad como investigación, más allá de la recuperación:

  • El DTB de fábrica — verdad fundamental para el árbol de dispositivos de esta placa, y el desempate cada vez que el dtsi del SoC hermano discrepa.
  • Blobs de firmware y su orden de carga — lo que realmente envía el stack del proveedor y dónde espera encontrarlo.
  • La línea de comandos del kernel del proveedor y el diseño de la imagen de arranque — offsets, versión del encabezado, y los argumentos que se le dieron al kernel de fábrica.
  • La cadena exacta de la versión del kernel — uname -a o /proc/version desde la ROM de fábrica, mientras aún se pueda leer (también se puede descomprimir más tarde de la imagen de arranque respaldada). Es la huella dactilar que selecciona la versión correcta de la fuente OEM publicada bajo GPL en la fase 2; los proveedores envían varias compilaciones y difieren.
  • Configuraciones del proveedor — configuraciones de sensores, módem y HAL que describen las interfaces que el controlador principal tendrá que satisfacer.

Finalmente, establece las convenciones de trabajo que el resto de la sesión asumirá: un directorio en el host que acumule un subdirectorio por arranque para registros y pstore, y una nota de qué ruta de recuperación se sabe que funciona. Si ya existe una copia de seguridad de un intento anterior, confirma que cubre estas particiones y que sus hashes aún se verifican, en lugar de asumirlo.

1. Recopilar evidencia del dispositivo en vivo primero

Captura el dmesg completo de la ejecución fallida antes de cambiar nada. Habilita los knobs de depuración relevantes antes de reproducir (por ejemplo, echo 0xffffffff > /sys/module/<driver>/parameters/debug_mask), porque una segunda reproducción cuesta otro arranque.

Canales de evidencia, en orden aproximado de fiabilidad:

  • Shell en vivo a través de la red o USB. El canal más barato; úsalo para cualquier cosa que el dispositivo sobreviva.
  • pstore. Una vez que systemd está activo, recoge de /var/lib/systemd/pstore/, no de /sys/fs/pstore/ — systemd-pstore.service mueve cada registro al principio del arranque, así que un /sys/fs/pstore/ vacío no es evidencia de que no se haya registrado un bloqueo. La región de la consola es típicamente una sola ranura: cópiala al host antes de hacer cualquier otra cosa, o el siguiente bloqueo la sobrescribe también en el archivo.
  • ramoops. Trátalo como con pérdida. La retención de carga de DRAM decae en el intervalo sin energía — medido aproximadamente en un 6,5 % de bits en un dispositivo, suficiente para fallar ECC en los encabezados de zona y perder un registro por completo. Busca en los registros difusamente. Lo que pudre la región es el tiempo sin energía, no el tiempo pasado enviando spam antes de cortar la energía, así que deja que un dispositivo bloqueado registre todo el tiempo que la zona de la consola pueda contener, luego apaga y enciende rápidamente. Verifica el tamaño de la zona antes de asumir que debes apresurarte: una zona de consola de 4 MiB absorbe horas de spam del watchdog antes de sobrescribirse.
  • Consola USB ACM a nivel de kernel (CONFIG_U_SERIAL_CONSOLE=y más console=ttyGS0 en la línea de comandos). El único canal que sobrevive a un bloqueo, y vale su costo único de flasheo al principio de un puerto. Un getty de ACM en espacio de usuario no sobrevive a uno — necesita una CPU programable, y produce cero bytes mientras aún se enumera bien a través de USB. Ambas mitades son necesarias: el símbolo de configuración solo deja la instalación inerte.

Cinco reglas que repetidamente convierten la inferencia en medición:

  • Confirma qué está realmente flasheado leyendo la partición de vuelta, nunca desde notas y nunca desde un registro de compilación. Lee con iflag=direct para que la lectura misma no perturbe lo que estás depurando. Cuidado con las comparaciones solo de tamaño — las imágenes de arranque están rellenadas a un tamaño fijo, así que la misma longitud en dos imágenes diferentes no prueba nada. Hashea el payload.
  • Leer una interfaz de depuración puede fabricar el síntoma. Los nodos de estado de fallo de DRM/GPU son el caso clásico: muestrear uno mientras la GPU está enviando activamente sintetiza líneas de fallo y recuperación que nunca ocurrieron (medido: cinco lecturas, cinco pares de fallo/recuperación, frente a ninguno sin observación). Antes de confiar en una línea de registro, verifica si tu propia observación la produjo.
  • Captura la respuesta cruda de un rechazo antes de interpretar el errno mapeado. El error mapeado de una llamada de firmware era ambiguo — EINVAL podría significar codificación incorrecta o política rechazada — hasta que la depuración dinámica en el envoltorio de la llamada expuso las palabras de respuesta crudas: una llamada bien formada que lleva un rechazo explícito. Eso es política, no codificación — el veredicto opuesto, con el siguiente paso opuesto. Clasifica cada rechazo de firmware como codificación incorrecta, rechazado por política, o no encontrado antes de actuar sobre él. La regla espejo: un negativo limpio y bien formado es prueba positiva — un "no encontrado" de una búsqueda bien formada valida la codificación y elimina una rama del plan sin tocar nunca el cargador.
  • Una medición que compite con una condición no controlada devuelve un número plausible y vacío. Un benchmark obtuvo 55 en dos segundos: el compositor mantenía DRM master, cada escena fallaba, y el número parecía real hasta que se verificó la condición. La comparación válida — 132 → 485 — necesitaba el compositor detenido para ambas ejecuciones, comparado solo dentro de esa generación. Antes de confiar en un benchmark, nombra la condición que podría anularlo y verifica que se mantuvo para cada ejecución.
  • Registra las reglas que retiras. El porte acumula folklore rápidamente, y una regla que era correcta para una revisión de hardware o un tamaño de búfer se vuelve activamente engañosa después de que cambia. Mantén la versión descartada junto a la actual con lo que cambió, para que la próxima sesión sepa qué consejo ha sido probado bajo estrés.

A tener en cuenta en el host:

  • timeout N ssh <device> '<cmd>' mata solo al cliente local; el proceso remoto sigue ejecutándose. Haz un seguimiento con un kill explícito.
  • pgrep -f y pkill -f se ejecutan sobre esa misma ruta ssh y se auto-coinciden con su propio shell remoto. Filtra el coincidente, o coincide por PID.
  • find necesita -L cuando la ruta de inicio es un enlace simbólico, o devuelve silenciosamente vacío.
  • Cualquier envoltorio o hook que reescriba la salida del comando — filtros de tokens, paginadores, formateadores — corromperá la evidencia, a veces invirtiendo una prueba en lugar de romperla obviamente. Usa el comando sin procesar para cualquier cosa que comprometas como hallazgo.

2. Investigar antes de implementar — todas estas fuentes

La investigación siempre precede a la implementación. Lo que consume depende de lo que estés haciendo:

  • Investigando un fallo — la evidencia de la fase 1. Captúrala primero; investigar un síntoma que no has leído realmente es adivinar con citas.
  • Añadiendo una capacidad — un controlador, un periférico, un subsistema que nunca ha aparecido — los artefactos de la fase 0 son los datos del dispositivo. El DTB de fábrica, las configuraciones del proveedor y el diseño del firmware describen cómo esta placa espera que se maneje la cosa, y son tan autoritarios aquí como un registro de fallo lo es allí.

De cualquier manera, antes de escribir algo:

  1. Razona sobre el subsistema — identifica qué controlador, enlace o interfaz de firmware posee el fallo, o poseería la nueva capacidad. Las habilidades disponibles para ti están listadas en tu contexto de sesión: escanea esa lista ahora, y si tiene una habilidad de desarrollo de kernel o análisis de fallos, léela antes de continuar — su detalle a nivel de registro y enlace es exactamente lo que este paso necesita. Razona directamente solo cuando no haya ninguna listada.
  2. Busca las bibliotecas y herramientas de espacio de usuario involucradas — documentación actual, no API recordada. Si una habilidad de recuperación de documentación está en esa misma lista de sesión, ejecútala en lugar de recordar firmas de memoria.
  3. Investigación web en las seis familias de fuentes (los subagentes paralelos funcionan bien aquí; si una habilidad de investigación web está en esa lista, prefierela por el almacenamiento en caché, ya que las sesiones releen las mismas páginas):
    • Mainline — lore.kernel.org, el código fuente del controlador, enlaces de DT, y el dtsi del SoC hermano más cercano (misma familia, o misma generación de RPM). Antes de planificar una campaña de "portar el controlador del proveedor", revisa lo que mainline ya tiene para la interfaz: su API exportada, si llega al espacio de usuario o es solo interno del kernel, y sus puertas — listas blancas de máquinas, semánticas de "precargado por el bootloader", empotrado en lugar de módulo (medido: una revisión así redujo un puerto de 9.4k líneas del proveedor a un módulo de sonda de ~300 líneas, porque mainline ya llevaba la interfaz internamente detrás de una lista blanca — el plan se convirtió en usar la API existente, no portarla).
    • Kernel del proveedor — la fuente OEM publicada bajo GPL. GPLv2 obliga a los OEM de Android a publicar las fuentes del kernel que enviaron, por lo que generalmente existe una versión exacta para este dispositivo: el portal de código abierto del OEM (Samsung, Sony, Xiaomi, Fairphone, OnePlus/OPPO y Motorola tienen uno), sus espejos de GitHub/GitLab, y archivos comunitarios como XDA cuando un enlace del portal ha muerto. Selecciona el tarball cuya cadena de versión coincida con /proc/version de la fase 0 — los proveedores publican varias, y difieren. La calidad de cumplimiento varía, así que trata el árbol como un oráculo para extraer — el dts de la placa y el defconfig para este dispositivo exacto, y los controladores del proveedor fuera del árbol (táctil, panel, cargador, pegamento de módem) con sus secuencias de registro y apretones de manos de firmware — en lugar de asumir que compila. Cuando no surja una versión exacta, la versión de un dispositivo hermano generalmente aún lleva el dtsi del SoC. Mejor aún: el DTB de fábrica extraído del dispositivo mismo (dd la ranura de arranque sin tocar, busca d00dfeed, dtc -I dtb -O dts). Esa es la verdad fundamental para esta placa y ha corregido suposiciones incorrectas de SoC hermano más de una vez — incluyendo un ID de flujo SMMU que el SoC hermano tenía mal y el DTB de fábrica tenía bien.
    • postmarketOS — paquetes de dispositivo pmaports y APKBUILDs, solicitudes de fusión, páginas wiki de dispositivos, y el árbol SoC-mainline.
    • Halium / UBports — árboles halium/android_device_*, configuraciones hybris-boot, y puertos de dispositivos UBports. Halium ejecuta el stack del proveedor de Android en lugar de mainline, lo que lo convierte en la mejor fuente de cómo el firmware del proveedor espera ser manejado: rutas de blobs de firmware y orden de carga, las interfaces de propiedades y sockets que los daemons esperan, configuraciones de HAL de sensores y módem. Cuando un controlador mainline sondea pero el apretón de manos del firmware falla — o cuando necesitas saber qué apretón de manos espera un periférico aún no soportado — aquí es donde generalmente está escrita la pieza faltante.
    • Mobian — los repositorios de dispositivos Debian.
    • NixOS — patrones mobile-nixos y empaquetado nixpkgs.

Los resultados escasos son el caso normal, no un bloqueo. La mayor parte de lo que un puerto necesita nunca se ha hecho en esta placa, y a menudo ni siquiera en este SoC. Seis fuentes que no reportan nada significa que nadie ha publicado el trabajo — nunca significa que el trabajo deba detenerse o devolverse. Cuando no hay precedentes, las respuestas aún están en los artefactos primarios: el controlador del proveedor fuera del árbol que ya maneja el periférico (secuencias de registro, apretón de manos de firmware, cableado GPIO y regulador), el propio nodo del DTB de fábrica para él, la configuración HAL del proveedor que nombra lo que el espacio de usuario espera, y el controlador mainline más cercano para la misma clase de dispositivo como plantilla estructural. Léelos, deriva el diseño, y escribe la pieza faltante — un nodo DT, un quirk, un controlador pequeño. Crear esa pieza es el estado terminal ordinario de un porte, no una excepción que deba justificarse; la copia de seguridad de la fase 0 y la regla de una variable por flasheo existen precisamente para que una derivación incorrecta cueste un arranque y una línea de registro, igual que cualquier otra refutación.

Un barrido vacío y un escaneo vacío son hallazgos diferentes. Un barrido vacío de las fuentes significa que nadie ha publicado el trabajo. Un escaneo vacío — una extracción que no devuelve nada — es nulo hasta que el mismo método se haya ejecutado contra un positivo conocido y su cobertura se haya verificado: recuentos de archivos, listas de segmentos, qué coincidió realmente el glob. Casi errores medidos: un glob coincidió con 9 de 27 segmentos de firmware y casi registró un falso "el firmware lo omite"; un escaneo de biblioteca solo se volvió confiable una vez que encontró un ID de chip conocido como control positivo.

Los identificadores del proveedor son del proveedor... (continuará...)


El contenido proporcionado es una traducción al español de la skill original, siguiendo las reglas especificadas. Se ha preservado la estructura Markdown, y el código, comandos CLI, rutas de archivo, nombres de variables de entorno, URLs y fragmentos de código en línea se han mantenido intactos. La traducción ha sido adaptada para sonar natural en español técnico.

Skills relacionados