Communitygithub.com

Linux Phone Porting

Uma skill de agente de codificação para ajudar você a portar Linux mainline para um telefone [Android?]

O que é Linux Phone Porting?

Esta skill é projetada para desenvolvedores e entusiastas que desejam portar o kernel Linux mainline para dispositivos móveis, especialmente telefones Android. Ela fornece um fluxo de trabalho rigoroso e passo a passo para reduzir o tempo de depuração e aumentar a taxa de sucesso de correções. A skill é útil porque estabelece uma ordem fixa de operações: desde o backup completo das partições do dispositivo (exceto dados do usuário), passando pela captura de evidências de falhas através de canais como pstore e console USB ACM, até a pesquisa aprofundada em seis famílias de fontes (mainline, kernel downstream, postmarketOS, Halium/UBports, Mobian e NixOS). Ela suporta plataformas como Claude Code, Cursor, Codex e outros agentes de IA que integram skills de desenvolvimento. O funcionamento baseia-se na análise de artefatos do dispositivo (DTB, firmware, cmdline do kernel) e na aplicação de regras de medição para evitar inferências falsas, como confirmar o que foi gravado lendo a partição de volta e classificando cada rejeição de firmware. A skill também enfatiza a importância de registrar regras que foram retiradas, evitando que conselhos desatualizados atrapalhem o progresso.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add angelwzr/linux-phone-porting

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que Linux Phone Porting faz?

Em um telefone sob integração mainline, uma iteração de depuração custa uma compilação mais um flash mais uma inicialização (5-10 min), e correções cegas são refutadas com muito mais frequência do que são aceitas. Siga esta ordem estritamente.

0. Configurar o port

Faça isso uma vez, antes do primeiro flash. Duas coisas fazem desta fase 0 e não papelada: o sistema original é a fonte de pesquisa de maior autoridade que você jamais terá para esta placa, e partes dele param de ser legíveis no momento em que você começa a sobrescrever partições.

Primeiro, estabeleça o alvo, porque cada resposta posterior depende dele:

  • Identidade exata do dispositivo — nome de marketing, codinome, SoC e a variante regional ou de armazenamento. Variantes irmãs do mesmo nome de marketing rotineiramente diferem em painel, controlador de toque ou modem, e uma correção pesquisada contra a variante errada parece plausível e falha.
  • Distro e init alvo — postmarketOS, Mobian, NixOS, Debian puro, outra coisa. Isso decide o empacotamento, o layout da imagem e qual das fontes da fase 2 está mais próxima de casa.
  • Topologia de inicialização — A/B ou não A/B, layout de slot e estado de bloqueio do bootloader. Apenas bootloaders desbloqueados. Se o bootloader estiver bloqueado, pare: esta skill não desbloqueia bootloaders e não fornece etapas de desbloqueio — aponte o usuário para as instruções do próprio OEM e retome quando o dispositivo estiver desbloqueado.
  • Recuperação — se uma recuperação personalizada está instalada. Não é um requisito: é uma conveniência para fazer backup e restaurar.

Em seguida, faça um backup completo de todas as partições exceto userdata:

  • Pule userdata: é a maior parte do espaço, são os dados do usuário e é a única partição que você pode perder.
  • Faça backup das partições exclusivas do dispositivo e nunca as publique. NV/EFS do modem, persist e suas irmãs de calibração carregam o IMEI, a calibração de rádio e o ajuste do sensor para este handset individual. Elas não são reproduzíveis a partir de nenhuma imagem na internet, e um port que as corrompe deixa um telefone que não pode se registrar em uma rede. Trate-as como críticas e privadas.
  • Faça hash de cada imagem e registre os hashes juntamente com a tabela de partições ao lado delas. Mais tarde, você precisará responder "o que está no dispositivo ainda é o que eu fiz backup", e apenas um hash responde a isso.
  • Verifique se o backup é realmente restaurável antes do primeiro flash arriscado, não depois de um.

O que o backup vale como pesquisa, além da recuperação:

  • O DTB original — verdade fundamental para a árvore de dispositivos desta placa e o desempatador sempre que o dtsi do SoC irmão discordar dele.
  • Blobs de firmware e sua ordem de carga — o que a pilha do fornecedor realmente envia e onde espera encontrá-lo.
  • A cmdline do kernel do fornecedor e o layout da imagem de inicialização — offsets, versão do cabeçalho e os argumentos que o kernel original recebeu.
  • A string exata da versão do kernel — uname -a ou /proc/version da ROM original, enquanto ainda pode ser lida (também pode ser extraída posteriormente da imagem de inicialização com backup). É a impressão digital que seleciona a versão correta da fonte OEM publicada sob GPL na fase 2; os fornecedores enviam várias versões e elas diferem.
  • Configs do fornecedor — configurações de sensor, modem e HAL descrevendo interfaces que o driver mainline terá que satisfazer.

Finalmente, defina as convenções de trabalho que o restante da sessão assumirá: um diretório no lado do host que acumula um subdiretório por inicialização para logs e pstore, e uma nota de qual caminho de recuperação é conhecido por funcionar. Se um backup já existir de uma tentativa anterior, confirme que ele cobre essas partições e que seus hashes ainda verificam, em vez de assumir que sim.

1. Coletar evidências do dispositivo ativo primeiro

Capture o dmesg completo da execução com falha antes de mudar qualquer coisa. Ative os knobs de depuração relevantes antes de reproduzir (por exemplo, echo 0xffffffff > /sys/module/<driver>/parameters/debug_mask), porque uma segunda reprodução custa outra inicialização.

Canais de evidência, em ordem aproximada de confiabilidade:

  • Shell ativo pela rede ou USB. Canal mais barato; use-o para qualquer coisa que o dispositivo sobreviva.
  • pstore. Assim que o systemd estiver funcionando, colete de /var/lib/systemd/pstore/, não de /sys/fs/pstore/ — o systemd-pstore.service move cada registro para fora no início da inicialização, então um /sys/fs/pstore vazio não é evidência de que nenhuma falha foi registrada. A região do console é tipicamente um slot único: copie-a para o host antes de fazer qualquer outra coisa, ou a próxima falha a sobrescreverá também no arquivo.
  • ramoops. Trate como com perdas. A retenção de carga da DRAM decai ao longo do intervalo sem energia — medida em aproximadamente 6,5% dos bits em um dispositivo, suficiente para falhar a ECC nos cabeçalhos de zona e perder um registro completamente. Faça grep nos registros fuzzily. O que degrada a região é o tempo gasto sem energia, não o tempo gasto enviando spam antes de cortar a energia, então deixe um dispositivo travado registrar pelo tempo que a zona do console puder suportar, então desligue e religue prontamente. Verifique o tamanho da zona antes de assumir que você deve se apressar: uma zona de console de 4 MiB absorve horas de spam do watchdog antes de ser sobrescrita.
  • Console USB ACM em nível de kernel (CONFIG_U_SERIAL_CONSOLE=y mais console=ttyGS0 na cmdline). O único canal que sobrevive a um travamento e vale seu custo de flash único no início de um port. Um getty ACM em userspace não sobrevive a um travamento — ele precisa de uma CPU escalonável e produz zero bytes enquanto ainda enumera bem pelo USB. Ambas as metades são necessárias: o símbolo de configuração sozinho deixa a facilidade inerte.

Cinco regras que repetidamente transformam inferência em medição:

  • Confirme o que está realmente gravado lendo a partição de volta, nunca de notas e nunca de um log de compilação. Leia com iflag=direct para que a leitura em si não perturbe o que você está depurando. Cuidado com comparações apenas de tamanho — imagens de inicialização são preenchidas para um tamanho fixo, então comprimento igual em duas imagens diferentes não prova nada. Faça hash da carga útil.
  • Ler uma interface de depuração pode fabricar o sintoma. Os nós de estado de falha/GPU DRM são o caso clássico: amostrar um enquanto a GPU está ativamente submetendo sintetiza linhas de falha e recuperação que nunca ocorreram (medido: cinco leituras, cinco pares falha/recuperação, versus nenhum não observado). Antes de confiar em uma linha de log, verifique se sua própria observação a produziu.
  • Capture a resposta bruta de uma rejeição antes de interpretar o errno mapeado. A resposta mapeada de uma chamada de firmware era ambígua — EINVAL poderia significar codificação errada ou política recusada — até que a depuração dinâmica no wrapper da chamada expôs as palavras de resposta brutas: uma chamada bem formada carregando uma recusa explícita. Isso é política, não codificação — o veredito oposto, com o próximo passo oposto. Classifique cada rejeição de firmware como codificação errada, recusada por política ou não encontrada antes de agir sobre ela. A regra espelho: um negativo limpo e bem formado é prova positiva — um não encontrado de uma consulta bem formada valida a codificação e elimina um ramo do plano sem nunca tocar no carregador.
  • Uma medição competindo com uma condição não controlada retorna um número plausível e vazio. Um benchmark marcou 55 em dois segundos: o compositor segurava o DRM master, cada cena falhou e o número parecia real até que a condição foi verificada. A comparação válida — 132 → 485 — precisava do compositor parado para ambas as execuções, comparado apenas dentro dessa geração. Antes de confiar em um benchmark, nomeie a condição que poderia invalidá-lo e verifique se ela foi mantida para cada execução.
  • Registre as regras que você retira. A integração acumula folclore rapidamente, e uma regra que estava certa para uma revisão de hardware ou um tamanho de buffer se torna ativamente enganosa após mudar. Mantenha a versão anulada ao lado da atual, com o que mudou, para que a próxima sessão saiba qual conselho foi testado sob estresse.

Pegadinhas no lado do host que valem a pena prevenir:

  • timeout N ssh <device> '<cmd>' mata apenas o cliente local; o processo remoto continua em execução. Siga com um kill explícito.
  • pgrep -f e pkill -f executados nesse mesmo caminho ssh correspondem a si mesmos sua própria shell remota. Filtre o correspondente ou faça a correspondência por PID.
  • find precisa de -L quando o caminho inicial é um link simbólico, ou ele retorna vazio silenciosamente.
  • Qualquer wrapper ou gancho que reescreva a saída do comando — filtros de token, paginadores, formatadores — corromperá as evidências, às vezes invertendo um teste em vez de quebrá-lo obviamente. Use o comando bruto para qualquer coisa que você comprometerá como uma descoberta.

2. Pesquisar antes de implementar — todas essas fontes

A pesquisa sempre precede a implementação. O que ela consome depende do que você está fazendo:

  • Investigando uma falha — a evidência da fase 1. Capture-a primeiro; pesquisar um sintoma que você realmente não leu é adivinhar com citações.
  • Adicionando uma capacidade — um driver, um periférico, um subsistema que nunca surgiu — os artefatos da fase 0 são os dados do dispositivo. O DTB original, as configs do fornecedor e o layout do firmware descrevem como esta placa espera que a coisa seja dirigida, e eles são tão autoritários aqui quanto um log de falha é lá.

De qualquer forma, antes de escrever qualquer coisa:

  1. Raciocine sobre o subsistema — identifique qual driver, vínculo ou interface de firmware possui a falha, ou possuiria a nova capacidade. As skills disponíveis para você estão listadas no contexto da sua sessão: escaneie essa lista agora e, se ela tiver uma skill de desenvolvimento de kernel ou análise de falhas, leia-a antes de continuar — seus detalhes em nível de registro e vínculo são exatamente o que este passo precisa. Raciocine diretamente apenas quando nenhuma estiver listada.
  2. Consulte libs e ferramentas de userspace envolvidas — documentação atual, não API lembrada. Se uma skill de recuperação de documentação estiver nessa mesma lista de sessão, execute-a em vez de recordar assinaturas da memória.
  3. Pesquisa na web em todas as seis famílias de fontes (subagentes paralelos funcionam bem aqui; se uma skill de pesquisa na web estiver nessa lista, prefira-a para cache, já que as sessões releem as mesmas páginas):
    • Mainline — lore.kernel.org, o código fonte do driver, DT bindings e o dtsi do SoC irmão mais próximo (mesma família, ou mesma geração de RPM). Antes de escopear qualquer campanha "portar o driver downstream", varra o que a mainline já tem para a interface: sua API exportada, se ela atinge o userspace ou é apenas interna do kernel, e suas portas — listas de permissão de máquina, semântica "pré-carregada pelo bootloader", embutido em vez de módulo (medido: uma dessas varreduras reduziu um port downstream de 9.4k linhas para um módulo de probe de ~300 linhas, porque a mainline já carregava a interface internamente atrás de uma lista de permissão — o plano se tornou dirigir a API existente, não portá-la).
    • Kernel downstream do fornecedor — a fonte OEM publicada sob GPL. GPLv2 obriga os OEMs Android a publicar as fontes do kernel que enviaram, então um lançamento exato para este dispositivo geralmente existe: o portal de código aberto do OEM (Samsung, Sony, Xiaomi, Fairphone, OnePlus/OPPO e Motorola todos executam um), seus espelhos GitHub/GitLab e arquivos da comunidade como XDA quando um link do portal morreu. Selecione o tarball cuja string de versão corresponde a /proc/version da fase 0 — os fornecedores publicam vários, e eles diferem. A qualidade de conformidade varia, então trate a árvore como um oráculo para minerar — o board dts e defconfig para este dispositivo exato, e os drivers downstream fora da árvore (touch, painel, carregador, cola do modem) com suas sequências de registro e handshakes de firmware — em vez de assumir que ela compila. Quando nenhum lançamento exato surgir, um lançamento de um dispositivo irmão geralmente ainda carrega o dtsi do SoC. Melhor ainda: o DTB extraído do próprio dispositivo (dd o slot de inicialização intocado, escaneie por d00dfeed, dtc -I dtb -O dts). Essa é a verdade fundamental para esta placa e já corrigiu palpites errados de SoC irmão mais de uma vez — incluindo um ID de fluxo SMMU que o SoC irmão errou e o DTB original acertou.
    • postmarketOS — pacotes de dispositivo pmaports e APKBUILDs, solicitações de merge, páginas de dispositivo wiki e a árvore SoC-mainline.
    • Halium / UBports — árvores halium/android_device_*, configs hybris-boot e ports de dispositivo UBports. Halium executa a pilha do fornecedor Android em vez da mainline, o que a torna a melhor fonte para como o firmware do fornecedor espera ser dirigido: caminhos de blob de firmware e ordem de carga, as interfaces de propriedade e socket que os daemons esperam, configs de HAL de sensor e modem. Quando um driver mainline faz probe mas o handshake de firmware falha — ou quando você precisa saber qual handshake um periférico ainda não suportado espera — este é geralmente onde a peça faltante está escrita.
    • Mobian — os repositórios de dispositivo Debian.
    • NixOS — padrões mobile-nixos e empacotamento nixpkgs.

Resultados finos são o caso normal, não um bloqueador. A maior parte do que um port precisa nunca foi feito nesta placa, e frequentemente nem neste SoC. Seis fontes relatando nada significa que ninguém publicou o trabalho — nunca significa que o trabalho deve parar ou ser devolvido. Quando um precedente está ausente, as respostas ainda estão nos artefatos primários: o driver downstream fora da árvore que já dirige o periférico (sequências de registro, handshake de firmware, fiação GPIO e regulador), o próprio nó do DTB original para ele, a config HAL do fornecedor nomeando o que o userspace espera e o driver mainline mais próximo para a mesma classe de dispositivo como um modelo estrutural. Leia-os, derive o design e escreva a peça faltante — um nó DT, uma peculiaridade, um pequeno driver. Autoria dessa peça é o estado terminal comum de uma integração, não uma exceção a ser justificada; o backup da fase 0 e a regra de uma variável por flash existem precisamente para que uma derivação errada custe uma inicialização e uma linha de livro, o mesmo que qualquer outra refutação.

Uma varredura vazia e um escaneamento vazio são descobertas diferentes. Uma varredura vazia das fontes significa que ninguém publicou o trabalho. Um escaneamento vazio — uma extração que não retorna nada — é nulo até que o mesmo método tenha sido executado contra um positivo conhecido e sua cobertura seja verificada: contagens de arquivos, listas de segmentos, o que o glob realmente correspondeu. Quase-erros medidos: um glob correspondeu a 9 de 27 segmentos de firmware e quase registrou um falso "o firmware o omite"; um escaneamento de biblioteca só se tornou confiável depois que encontrou um chip id conhecido como seu controle positivo.

**Identificadores downstream são de downstream...

Habilidades Relacionadas