
Guia passo a passo para compilar kernels Kali NetHunter personalizados para Android: obtenção do código-fonte, seleção da toolchain, compilação cruzada e flashing.
O maior obstáculo para a maioria das pessoas que querem configurar um dispositivo Nethunter é o requisito do kernel. A menos que o seu dispositivo já tenha um kernel pré-construído (e mantido), vão dizer-lhe para compilar um você mesmo/a. Já existe muita documentação sobre este processo, mas na minha experiência pode ser difícil saber o que se aplica ao seu caso e o que não se aplica.
Este problema é agravado por parvos pessoas que escrevem guias com títulos de clique como "Compila um kernel Nethunter para QUALQUER dispositivo Android!" ou com falsas promessas como "Aprende a compilar um kernel Nethunter em dez minutos!" É também uma infeliz realidade da internet em 2025 que muitos idiotas pensam que o ChatGPT ou outros grandes modelos de linguagem têm respostas autoritativas para as suas perguntas, quando tudo o que esses modelos realmente têm é informação que rasparam dos parvos acima mencionados.
Estou a escrever este guia da forma mais completa e honesta que consigo. No entanto, não pretende ser o único documento que vai precisar de ler para este processo – certamente terá perguntas que este documento não consegue responder. Gostaria de o encorajar a procurar respostas para essas perguntas na documentação de software relevante, e NÃO no YouTube ou no ChatGPT.
Antes de começar QUALQUER parte deste processo, já deverá ter:
apt update && apt upgrade -y (opcional: adicionados metapacotes)Para concluir este processo, vai precisar de:
cd, rm, ls, mkdir, find, diff, grep, etc)vim para os fixes, caso contrário nano)build-devel em distros baseadas em Arch, build-essential nas baseadas em Debian) – também recomendo instalar Perl + Python3, pois alguns makefiles de kernel exigem estesIsto vai ser possível para o meu dispositivo?
O kernel Linux é licenciado sob a GNU General Public License 2.0, que é uma licença copyleft. Isto significa que o código-fonte do kernel Linux é distribuído livremente e pode alterar o código-fonte como desejar (como cada fabricante Android fez), NO ENTANTO, o código-fonte resultante TAMBÉM deve ser distribuído livremente.
Para surpresa de absolutamente ninguém, muitas das gigantescas corporações que utilizam código licenciado pela GPL desrespeitam os termos desta licença. Ou recusam-se a distribuir o seu código-fonte ou apenas publicam parte dele (geralmente avariado, desatualizado e com blobs binários inline). Se não houver código-fonte disponível para o kernel do seu dispositivo, então não há forma de criar um kernel Nethunter para ele.
A sua capacidade de desbloquear o bootloader e instalar uma ROM personalizada também depende muito dos caprichos do fabricante do seu dispositivo. Mesmo que permitam o desbloqueio do bootloader e você tenha conseguido obter root no seu telemóvel com o Magisk, se não publicarem device trees, provavelmente não existem ROMs personalizadas para o seu dispositivo. Nesse caso, é extremamente duvidoso que o código-fonte do kernel que publicaram (se o fizeram) tenha recebido alguma manutenção desde a sua publicação, ou que compile mesmo sem modificações. Se você não vir mais ninguém a manter qualquer coisa (kernels, ROMs, recoveries) para o seu dispositivo, então será difícil, senão impossível, transformar esse dispositivo num Nethunter completo.
Uma Nota Sobre Versões de Kernel
Imaginemos que existem ROMs/kernels/recoveries personalizadas atualizadas e mantidas regularmente para o seu dispositivo, mas simplesmente não existe um kernel Nethunter. Nesse caso, deverá conseguir concluir este processo, mas o processo variará dependendo de qual versão do kernel Linux o seu dispositivo usa.
A informação neste guia é baseada na minha experiência a modificar kernels 4.14.x. Existem guias mais antigos que falam sobre utilizar toolchains GCC (em vez de LLVM/clang, como vamos usar) que se aplicam a kernels 3.x. Se o seu dispositivo utiliza uma versão 5.x/6.x do kernel Linux, então a informação neste guia não será suficiente para concluir este processo. O método de compilação Android muda constantemente, e deve procurar um guia que cubra kernels GKI e a utilização de Bazel/Kleaf.
Uma boa forma de encontrar repositórios que contêm o código-fonte do kernel para o seu dispositivo é usar o seu codinome. Todos os Android têm um, embora alguns fabricantes (ex.: OnePlus) se divirtam um pouco mais com isto do que outros (ex.: Samsung). O codinome do meu Xiaomi Poco X3 NFC é "surya", enquanto o codinome do meu Samsung A51 é "SM-A515F". Normalmente, os repositórios de código-fonte do kernel seguem a convenção de nomenclatura
android_kernel_MANUFACTURER_CODENAME
onde o fabricante é a empresa-mãe, ou seja, android_kernel_xiaomi_surya, não android_kernel_poco_surya.
No entanto, também pode haver repositórios baseados no SoC (system-on-a-chip) do seu dispositivo, por vezes "unificados" para incluir ficheiros de código-fonte de outros dispositivos com o mesmo SoC. Este é o caso do Samsung que mencionei, cujo repositório de código-fonte se chama android_kernel_samsung_exynos9611. Dê uma vista de olhos pelo github/gitlab e veja o que consegue encontrar.
Para os fins deste guia, vou usar a LineageOS 22.2 mais recente (compilada em 2025-08-04) no surya, portanto, vou querer clonar o código-fonte do kernel do repositório da LineageOS. Mas antes de fazer isso, quero copiar dois ficheiros do meu dispositivo para o computador que usarei para compilar o kernel: /proc/config.gz e /proc/version.
Podia copiar o primeiro ficheiro, /proc/config.gz, para /sdcard, puxá-lo do dispositivo com ADB, descomprimi-lo com gunzip e renomeá-lo. Mas isso parece ser muitos passos, então o que fiz em vez disso foi isto:

Depois, no próprio dispositivo, executei (como root)

O que está a acontecer aqui?
No meu portátil: nc (netcat) -l (ficar à escuta de ligações de entrada) -p (porta) 4545 (na verdade, podia ser qualquer número entre 1024-65535, mas costumo usar 4545) > (escrever para ficheiro) surya-defconfig-lineageos22.2-20250804 (nome de ficheiro descritivo) < (entrada a partir do ficheiro) /dev/null (dispositivo nulo – isto garante que se eu tocar no teclado não enviará a tecla para o ficheiro que estou a receber, potencialmente estragando-o).
No telemóvel: zcat (como o comando cat para concatenar, mas para ficheiros gzip) /proc/config.gz (a configuração do kernel com a qual o kernel atualmente em execução foi compilado) | (enviar a saída desse processo como entrada para o próximo processo) nc (netcat novamente) 192.168.1.42 (o endereço IP local do meu portátil) 4545 (porta que defini antes)
Embora isto deva fornecer-lhe o ficheiro .config que foi usado para compilar o kernel atualmente em execução, nem sempre é o caso. Alguns dispositivos mais modernos/builds de ROM mais recentes recusam-se a arrancar se a configuração guardada em /proc/config.gz não corresponder ao .config que foi usado para compilar o kernel de fábrica. Felizmente, esse é o único controlo que ocorre (não algo muito mais difícil de contornar como uma soma de verificação SHA256 do kernel inteiro), então algumas pessoas inteligentes arranjaram uma forma de falsificar o ficheiro em /proc/config.gz para corresponder ao kernel de fábrica, apesar das suas modificações. Se não tiver a certeza se o ficheiro no seu dispositivo é real ou falsificado, pode executar zcat /proc/config.gz | head e depois uname -r. Se os números de versão não coincidirem, então o ficheiro em /proc foi falsificado. Nesse caso, embora ainda possa avançar com este guia, poderá querer executar diff para comparar a configuração extraída com alguns dos ficheiros que encontrar no diretório arch/arm64/configs do código-fonte do seu kernel.
Quanto a /proc/version, talvez não seja tão necessário enviar esse ficheiro, pois tudo o que realmente precisamos é da informação sobre qual versão de clang/ld.lld foi usada para o compilar. Então podemos simplesmente executar cat /proc/version e dar uma vista de olhos:

Ah, pois! Parece que quem compilou este kernel fez uma pequena "asneira" e o Makefile deles registou todas as -CFLAGS que executaram com clang, mas não a versão do Clang. No entanto, podemos ver que usaram uma toolchain Android pré-construída, e que usaram ld.lld versão 19.0.1.
Aqui está uma imagem ligeiramente mais útil. A primeira saída é de /proc/version antes de modificar, compilar e instalar um novo kernel no Samsung A51. A segunda saída é de /proc/version atualmente.

Estás a notar alguma coisa? (Não, não o meu estranho nome de utilizador e hostname).
O melhor truque para escolher uma toolchain é usar a toolchain EXATA que compilou o kernel atualmente em execução.
Neste caso, foi Neutron clang 18.0.0git, que foi bastante fácil de encontrar:

E olha só, os md5sums coincidem e tudo.
Só por diversão, vamos dar uma vista de olhos rápida à string /proc/version de um dispositivo consideravelmente mais antigo, Samsung J7 (2016), codinome j7xelte:

Este é um dispositivo suficientemente antigo que ainda usava toolchains GCC para compilar o kernel.
Mas quando pesquiso por "gcc version 4.9.x 20150123 prerelease", encontro dois repositórios:

Então qual devo descarregar?
A resposta: ambos. O GCC é diferente do Clang no sentido em que, ao compilar compiladores/binutils/ligadores/etc para cross-compiling, é necessário construir uma toolchain separada para cada "target triple". O target triple (supostamente) tem o formato
machine-vendor-operating_system
Mas como veremos, esta "regra" tem um milhão de exceções. Mas vamos começar com "machine".
Na secção "vai precisar de" deste documento, disse que precisava de um computador de 64 bits com processador Intel ou AMD a executar GNU/Linux. Isso porque as toolchains que vamos usar são compiladas para serem executadas em x86_64-linux-gnu.
No entanto, estas toolchains são cross-compilers, o que significa que o código de máquina que geram a partir dos ficheiros de código-fonte C não será executado nesse computador, mas sim num diferente com o seu próprio target triple.
Aarch64, também conhecido como arm64, é a arquitetura que quase todos os dispositivos Android usam. Arm, sem o "64", refere-se às implementações de 32 bits dos chips ARM. A maioria dos kernels Android é compilada usando tanto o triple aarch64 como o arm, para fornecer retrocompatibilidade com software de 32 bits.
Avançando para a próxima parte: "Linux". Dispensa explicações. É um kernel Linux.
Mas a última parte destes "triples" merece uma explicação, pelo menos breve, porque é uma confusão tão enrolada que cada compilador que usa "triples" (GCC, Rust, Go, LLVM) fá-lo de forma ligeiramente diferente. "Android", o primeiro exemplo, faz sentido, mas o que é "androideabi?" EABI significa "embedded application binary interface", mas realmente não tem de se preocupar muito com isso – vamos apenas considerar EABI como o terceiro valor "base". Também verá "gnueabi", que agora faz um pouco mais de sentido – a implementação GNU do EABI, certo? (O que isto realmente refere é a biblioteca C do GNU, glibc, que é a razão pela qual também verá triples como arm-linux-musleabi ao compilar contra uma biblioteca C alternativa como musl). Também poderá ver "gnueabihf." HF significa "hard float", e se quiser saber como a ARM implementou uma solução no chip para operações de ponto flutuante, vá ler um artigo da Wikipédia.
Aqui está o que precisamos de saber:
Se estiver a usar uma toolchain LLVM, vamos declarar a nossa intenção de fazer cross-compile definindo CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi- (assim, com o - no final) na linha de comandos.
Se estiver a compilar para um dispositivo muito antigo e, portanto, a usar uma toolchain GCC, precisaremos de dois conjuntos de ficheiros, prefixados com triples diferentes. Estes podem ser os mesmos que os valores do exemplo LLVM, ou podem ser diferentes, como nas toolchains para j7xelte.
Mas PORQUE há tantas formas de escrever a mesma coisa? i386, i686, 386, i32, i64, x86, x64, x86_64, amd64 -- que razão possível pode haver para tanta variação?!
Banda desenhada relevante do xkcd:

Voltando ao exemplo que vou compilar hoje (surya), aconteceu-me guardar a informação de /proc/version de outro kernel, que dizia:

Isto é mais ou menos como deve parecer, com o link, checksums, versões do compilador/ligador, etc. E como as versões de clang e LLD aqui eram ambas 17.0.3 e o /proc/version malformado que temos da LineageOS atual mostra LLD 19.0.3, acho que é razoável procurarmos uma toolchain que tenha 19.0.3 para ambos.
Depois de cerca de três minutos de pesquisa, encontrei um repositório que podemos clonar como submódulo (para facilitar uma compilação reproduzível) aqui: https://gitlab.com/kei-space/clang/r536225/ Essa toolchain acabou por ter problemas graves, então optei pelo Neutron Clang 19. (Vamos voltar a isto).
Então temos a nossa fonte e a nossa toolchain prontas a clonar, o que nos leva a:
Decidi criar um novo utilizador para este tutorial, principalmente para poder usar gh auth login e executar commits sem os fazer acidentalmente na minha conta github principal. Mas para isso, tive de criar uma conta (num navegador), configurar um novo utilizador, gerar chaves SSH para eles…

Copie .ssh/id_ed25519.pub para o GitHub e depois execute gh novamente no terminal

E depois estou pronto

…quase. Ainda tenho de fazer fork do repositório no meu navegador,

e depois inicializá-lo/cloná-lo no terminal.

Assim que tudo estiver pronto (fontes atualizadas, origin definida, etc) podemos começar a clonar submódulos.

A sintaxe é git submodule add URL directory/

Lembre-se, para um histórico de commits muito limpo, queremos executar git add . e git commit -a após cada alteração.

Não vou executar git push ainda, mas quando eventualmente o fizer, atualizará todos os commits.
Aqui é onde provavelmente está à espera que o guia fale sobre fazer modificações ao código-fonte do kernel para adicionar suporte Nethunter. Isso está a chegar – em breve. PRIMEIRO, no entanto, vamos ver como o código-fonte não modificado compila com a nossa toolchain e configuração.

Essa configuração do kernel atualmente em execução precisa de ser copiada para o diretório do código-fonte do kernel, mas como vamos usar out/ para os nossos binários compilados, também preciso de a copiar para lá. Também preciso de acrescentar à minha variável PATH o diretório bin/ da toolchain. Podia escrever export PATH=/home/build_user/android_kernel_xiaomi_surya/toolchain/bin:$PATH, mas uma forma mais fácil é simplesmente cd para esse diretório e depois executar export PATH=$(pwd):$PATH. $() expande para o resultado do comando que contém, e pwd listará o caminho completo para o diretório de trabalho atual.
Também listei o conteúdo do diretório bin/ da toolchain para que possa ver como os binutils LLVM têm o seu próprio prefixo. Idealmente, o Makefile contém uma instrução onde, se eu declarar LLVM=1, ele define automaticamente AR=llvm-ar, AS=llvm-as, etc. Então vamos ver o que está no Makefile.

Excelente! Posso simplesmente declarar LLVM=1 e não ter de declarar individualmente o resto… na maioria dos casos. Também preciso de usar o assembler LLVM, mas isso tem a sua própria declaração, LLVM_IAS:

Então agora tudo o que preciso de declarar é ARCH=arm64 LLVM=1 LLVM_IAS=1 AS=llvm-as O=out CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi-. Isso pode parecer muito, mas é muito menos do que declarar cada binutil individualmente.
Então vamos executar o nosso comando para abrir a configuração….
Espera. Parece que esta toolchain tem alguns problemas. Então decidi remover a inicialização do submódulo (deinit) e em vez disso obter Neutron Clang 19.0.0 de aqui, e vou descarregar isso com wget

Depois extrair para um diretório toolchain/ recém-criado (esquecendo-me da sintaxe para extrair ficheiros .tar.zst no início)

E depois adiciono este diretório ao ficheiro .gitignore.
Agora quando executo isto:

Funciona, abrindo o menu nconfig:

Muitos tutoriais dir-lhe-ão para usar o menuconfig, mas prefiro nconfig porque 1) parece melhor 2) não tem a mesma tendência que o menuconfig tem de não carregar porque não consegue encontrar as bibliotecas ncurses que já instalou. Em qualquer caso, isto é apenas um kernel de teste, então podemos carregar .config e guardá-lo (novamente como .config) e terminámos por agora.
E agora tentamos compilar Image.gz, e…

O nosso primeiro erro! Hurra!
De acordo com isto, isto acontece porque uma atualização do Arch partiu algo.
Embora o Arch tire, o Arch também dá, neste caso na forma do pacote AUR libxml-legacy. Então instalei isso, executei make novamente, e desta vez:

Parabéns aos mantenedores da LineageOS, porque o kernel inteiro compilou com apenas um aviso:

Então agora em out/arch/arm64/boot/ podemos encontrar Image.gz. Mas como faríamos o flash disto para o nosso dispositivo?
Precisamos de criar um zip AnyKernel3.
Há duas formas de o fazer:
Image, pode ser o Image.gz que criamos e nada mais, pode ser Image.gz-dtb (uma imagem combinada de device tree/kernel – essas são menos comuns hoje em dia, mas se o seu dispositivo esperar uma, você terá que habilitar “Build a concatenated Image.gz-dtb” na configuração do kernel), ou pode ser Image.gz, dtbo.img e/ou dtb.img.
Para os fins deste guia, baixei um dos muitos kernels distribuídos no Telegram com um nome de anime idiota e sem fonte vinculada. Nunca instale um desses kernels.
Mas não vamos fazer isso, não se preocupe, estamos apenas pegando emprestada a configuração do zip AnyKernel deles. Então renomeio e descompacto o arquivo

E editei o script anykernel.sh para alterar também a string do nome do kernel. Agora vamos sobrescrever o Image.gz desse zip com o nosso novo

Usar zip -f (para “freshen”, ou atualizar) simplesmente substituirá o arquivo interno pela nova versão. 0 é para compressão zero.
Vamos ver se consigo fazer flash deste kernel e se ele vai bootar, mas antes:

É muito mais fácil manter o controle dos zips de kernel quando você inclui strings de data e hora.

Porém, no interesse de ser completo (e de depender o mínimo possível de kernels do Telegram), vou te contar como criar seus próprios arquivos dtb.img e/ou dtbo.img, já que a documentação sobre isso é dolorosamente inadequada.
Existem dois programas AOSP para esse fim. Um deles, mkdtboimg, é escrito em Python, o que torna fácil simplesmente baixar e executar mkdtboimg.py do site oficial do AOSP. Porém, você também pode precisar do outro, mkdtimg, que é escrito em C e enviado sem Makefile. De acordo com a documentação, os arquivos Android.bp são suficientes — você só precisa fazer checkout do código AOSP inteiro para poder executar os comandos listados lá. Acho isso completamente insano, então peguei o Makefile que outra pessoa havia feito há muito tempo para compilar essa ferramenta de forma independente, atualizei os arquivos de origem com a versão mais recente e fiz um build static-PIE com Musl. Você pode baixar esse binário (que roda em qualquer computador Linux x86_64, como o que você está usando para compilar o kernel) aqui, ou compilá-lo você mesmo a partir do código-fonte.
Agora vem a parte complicada: os arquivos .dtbo produzidos durante a compilação do kernel não podem ser convertidos em dtb.img/dtbo.img sem um pouco de esforço extra. O Android precisa que a chamada ao dtc inclua a flag -a 64. Como já estamos chamando DTC_EXT=/usr/bin/dtc para forçar o Makefile a usar nosso DTC atualizado do gerenciador de pacotes e não o quebrado encontrado em muitos kernels, não é tão difícil simplesmente colocar esse comando entre aspas simples e adicionar a flag. Você pode simplesmente passar DTC_EXT='/usr/bin/dtc -a 64'. No meu caso, porém, gosto de criar (e testar) scripts build.sh para todos os kernels que mantenho, para que, mesmo sem ler este guia, qualquer pessoa, por mais n00b que seja, possa compilar o seu a partir do código-fonte. Enquanto eu lutava com camadas e mais camadas de lógica bash de aspas simples e duplas, encontrei uma solução simples, ainda que deselegante, que garante que o DTC seja chamado com a flag correta: um script wrapper.
Simplesmente criei um arquivo executável chamado dtc no diretório raiz do meu kernel, contendo as seguintes linhas:
#!/bin/sh
exec /usr/bin/dtc -a 64 $@
Então apontei DTC_EXT= para esse arquivo, e isso resolveu o problema.
Você deve estar se perguntando: “Que arquivos .dtbo? Meus builds de kernel nunca geram isso!” Nesse caso, verifique se este símbolo do kernel está habilitado:

Então, como usamos essas ferramentas? A primeira coisa que fiz foi analisar os arquivos dtb.img e dtbo.img que encontrei em outros zips de kernel para ver que tipo de arquivos eram. (Eu sei, eu sei, não queremos depender dos estranhos kernels da cena de ROMs customizadas para os nossos, mas isso vale a pena verificar). O comando file dtb.img retornou:
dtb.img: Device Tree Blob version 17, size=345849, boot CPU=0, string block size=31481, DT structure block size=314312
que é (quase) exatamente o mesmo resultado que obtenho ao executar file ../arch/arm64/boot/dts/qcom/sdmmagpie.dtb:
../arch/arm64/boot/dts/qcom/sdmmagpie.dtb: Device Tree Blob version 17, size=345856, boot CPU=0, string block size=31481, DT structure block size=314312
Essa pequena diferença me preocupou, até eu executar diff <(strings dtb.img) <(strings ../arch/arm64/boot/dts/qcom/sdmmagpie.dtb) e descobrir que eles continham exatamente as mesmas coisas. Então pude assumir com segurança que criar meu próprio dtb.img era só uma questão de copiar sdmmagpie.dtb e mudar o nome.
Quanto ao dtbo.img, não recebemos muita ajuda do file:
dtbo.img: data
Mas é aqui que podemos usar mkdtimg ou mkdtboimg.py para analisá-lo. Quando executo mkdtimg dump dtbo.img, obtenho:

Então sei que, ao criar o meu, devo passar
mkdtimg create dtbo.img --page_size=4096 ../arch/arm64/boot/dts/qcom/sdmmagpie-idp-overlay.dtbo
ou
mkdtboimg create --page_size=4096 dtbo.img ../arch/arm64/boot/dts/qcom/sdmmagpie-idp-overlay.dtbo
Ambos os comandos produzem arquivos idênticos. Você também pode executar mkdtimg dump dtbo.img depois e comparar os valores com o outro arquivo. Se precisar incluir mais de um arquivo .dtbo na sua imagem, basta acrescentar o caminho dele no final de qualquer um dos comandos.
Agora, de volta ao kernel de teste que criamos. A boa notícia é que ele fez flash sem problemas; a má notícia é que vou ter que consertar aquele Makefile que cria um /proc/version tão feio.
Mas isso pode esperar. Agora, finalmente, chegamos a:
Hora de adicionar alguns submódulos. Primeiro, este, que vem com instruções muito fáceis de seguir. (Edição: agora ele também contém os símbolos do subsistema CAN do kernel, já que meu pull request adicionando-os foi mesclado, embora você não veja isso nas capturas de tela abaixo).

E agora, quando executo make nconfig novamente (mesmo comando de antes)

Temos esta adorável opção nova

Isso habilitará todas essas coisas. Selecione isso, salve como .config – mas cuidado: isso salvará em out/.config, e excluiremos esse diretório inteiro antes de compilar novamente. Então, ao sair do nconfig, copie esse arquivo para o diretório do código-fonte do kernel.
Agora é hora de aplicar patches em alguns arquivos de origem; então vamos adicionar o repositório de scripts de build do Nethunter como submódulo:

Executamos cd para o novo diretório e rodamos ./build.sh, escolhendo a opção 4: Apply Nethunter kernel patches.

Se você receber alguma mensagem dizendo “the test run was completed with errors,” NÃO aplique o patch. Caso contrário, vá em frente. No meu caso, apliquei os patches 4, 5 e 8.
Agora que fizemos alterações, vamos voltar ao diretório raiz do código-fonte do kernel e fazer commit delas.

Neste ponto, você poderia simplesmente compilar o kernel novamente e pronto. Mas eu sou exagerado, e quero incluir suporte para um monte de coisas extras, a saber:

Vamos precisar modificar o Kconfig e o Makefile em drivers/net/wireless/realtek para que a configuração reconheça esses drivers recém-adicionados, mas também:

Certifique-se de trocar a plataforma no rtl8812au/Makefile para ANDROID_ARM64 (assim como para rtl8188eus).
Também vale a pena verificar o Kconfig dos drivers recém-adicionados para ver qual é o nome da opção de configuração:

Agora sei que preciso me referir a ela como 88XXAU no Makefile um nível acima.

Felizmente, o Kconfig é apenas incluído (sourced) assim:

Vou ter que editar esses arquivos novamente depois de adicionar também o rtl88x2bu e o branch ARM do rtl8188fu. (E, no fim das contas, a opção de configuração do rtl88x2bu se chama RTL8822BU, por isso sempre vale a pena conferir).
Agora, os drivers backportados da MediaTek. Usando este commit como guia, portei com sucesso esses drivers para dois dispositivos diferentes usando kernels 4.14.x. (Viu por que o histórico de commits é importante?) Mas primeiro precisamos do diretório mt76 com todos os seus arquivos.
Em vez de ter que fazer git clone de algum kernel 4.19 e copiar os arquivos de lá, e depois aplicar os patches necessários nesses arquivos na sua nova cópia, você pode simplesmente adicionar https://github.com/akabul0us/mt76.git como submódulo. Depois edite o Makefile e o Kconfig no diretório drivers/net/wireless/mediatek:

Ao adicionar este repositório com os patches do commit mencionado anteriormente já aplicados ao código-fonte, podemos pular para as modificações que precisamos fazer em outros arquivos do kernel. O primeiro é este:

Mas acontece que nosso código-fonte do kernel já tem essa struct:

Então passamos para o próximo arquivo a modificar, include/linux/overflow.h. Este tem algumas modificações, mas como são bem claras de ler no commit original, vou poupar você de mais capturas de tela. include/linux/skbuff.h e include/linux/scatterplot.h também têm alterações, mas nenhuma é necessária para include/net/cfg80211.h. As alterações necessárias em include/net/mac80211.h são pequenas – apenas inserir RX_ENC_HE, como linha final dentro de enum mac80211_rx_encoding { }, e adicionar u8 vht_flag; em struct ieee80211_rx_status { }. O arquivo net/wireless/of.c já existe e é igual ao do commit que estamos fazendo cherry-pick, então terminamos com isso. (Ufa!)
Quanto ao suporte a Docker, bom, graças (mais uma vez) ao cyberknight777 por isto, podemos simplesmente copiar e colar

E agora estamos prontos para rodar o nconfig de novo! ...quase. Primeiro, faça commit e push das alterações, depois rm -rf out/ (certificando-se de que salvou seu .config fora dali), mkdir -p out, e SÓ ENTÃO podemos voltar à configuração.

Uma observação sobre os drivers USB Realtek fora da árvore que adicionamos ao kernel: Eles meio que são uma porcaria. Se você tentar compilar mais de um deles embutido (inline), terá erros na hora da linkagem. Uma solução antiga é compilar apenas um (1) embutido e o restante como módulos. Os drivers da Mediatek, no entanto, podem ser compilados embutidos sem problema.
Acabei habilitando um monte de outras coisas; se quiser ver o diff completo, coloquei aqui – mas, de qualquer forma, vamos compilar!

Um bom começo - é sempre legal quando você vê novos arquivos objeto recém-adicionados sendo compilados sem erros ou avisos.

Isso? Menos legal, mas fácil de consertar. Só temos que remover -Wno-stringop-overread do Makefile que tiver isso como flag de aviso. E já que estamos nisso, -Werror é um pouco hardcore, você não acha? (Essa flag significa “tratar todos os avisos como erros”, parando a compilação em QUALQUER soluço, incluindo uma flag -W desconhecida).

Pelo menos este é fácil de consertar.

Um rápido # na frente dessa linha e estamos prontos para rodar o make novamente – e desta vez, ele foi até o fim!
Mas, como configurei alguns drivers como módulos, ainda não terminamos. Precisamos executar make modules, ou mais especificamente, make -j $(nproc --all) ARCH=arm64 O=out CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi- LLVM=1 LLVM_IAS=1 AS=llvm-as modules. E, nossa, o código do driver Realtek para rtl8188fu é um verdadeiro caos:

Eu poderia corrigir manualmente cada uma das linhas que causam esses avisos? Claro. Vou fazer isso? Não. Há um motivo pelo qual compilo esses drivers como módulos e não embutidos, e incentivo ativamente todos a evitar adaptadores baseados em Realtek. Porém:

Eles compilaram com sucesso, pelo menos. Voltaremos a eles em um momento. Primeiro, vamos atualizar nosso zip do kernel:

(Quase esqueci - este não é mais um kernel de “teste”, é um Nethunter de verdade).
Quanto aos módulos, arquivos .tar são realmente o caminho a seguir, porque preservam tudo sobre os arquivos que contêm – no entanto, também preservam caminhos. A menos que façamos algo sobre isso, ao extrair nosso tarball de módulos vamos criar um monte de diretórios, como drivers/net/wireless/realtek/rtl8188fu/rtl8188fu.ko, por exemplo. Então vamos criar um diretório (e adicioná-lo ao .gitignore), copiá-los para lá e, em seguida, criar o arquivo.

Você pode fazer flash deles como faria com um kernel?

Eles precisam ser extraídos em algum lugar do seu dispositivo. Digo “em algum lugar” porque não importa muito onde, contanto que, ao executar insmod /whatever/path/to/whatever.ko, o módulo carregue. Você pode fazer isso em /sdcard, tudo bem, mas lembre-se: eu sou exagerado, então vou extraí-los no lugar “adequado” para este dispositivo, /vendor/lib/modules. É claro que /vendor está montado somente leitura, então primeiro preciso abrir um shell root (NÃO no terminal do Nethunter – isso é um chroot – embora você possa usar o app do terminal do Nethunter se selecionar “New Session → Root Shell”) e executar mount -o rw,remount /vendor antes de poder fazer qualquer coisa nessa partição. Depois cd /vendor/lib/modules; tar xzvf /sdcard/or/wherever/you/saved/the/tarball.tgz; mount -o ro,remount /vendor e pronto, acabou com os módulos.
Se você receber um erro sobre falta de espaço nessa partição, também pode usar um link simbólico – guarde o arquivo em, por exemplo, /sdcard/modules, e então crie um link usando o caminho absoluto. Então, se fizéssemos isso com 88x2bu.ko, executaríamos ln -s /storage/emulated/0/modules/88x2bu.ko /vendor/lib/modules/88x2bu.ko.

Faça um último push no seu repositório e, se quiser, salve o .config que usou como um novo defconfig para o Nethunter. (Isso realmente ajuda quem compila a partir do código-fonte).
Funciona? Ele faz flash sem problemas, claro, mas será que funciona?
Bem, já está bem tarde aqui, então não vou testar absolutamente todos os recursos agora, mas vamos com o crucial: modo monitor/injeção de pacotes nos drivers que adicionei ao kernel. Vamos começar com rtl88x2bu:

Nada mal, para um driver Realtek.
E agora o evento principal: mt76x2u:

Agora sim, isso é um dispositivo de pentest!
O passo final é enviar seu .zip e .tar.gz para o github como um release. Depois, poste sobre isso no xdaforums, Telegram, Twitter, onde você achar que outros usuários do mesmo dispositivo/ROM vão encontrar e se beneficiar.
E quando algum otário ingrato de cu sujo responder ao seu post com “NOW U MAKE KARNEL FOR DEVICE BUTTPHONE 34AC PRO EDITION?!!?”, dê a eles o link deste guia e diga para eles “git gud”.
Boa noite a todos.
--Akabul0us