
Guida passo-passo alla creazione di kernel Kali NetHunter personalizzati per Android: recupero del sorgente, selezione della toolchain, cross-compilazione e flashing.
L'ostacolo più grande per la maggior parte delle persone che vogliono configurare un dispositivo Nethunter è il requisito del kernel. A meno che il tuo dispositivo non abbia già un kernel precompilato (e mantenuto), ti verrà detto di compilarne uno da solo. Esiste già molta documentazione su questo processo, ma dalla mia esperienza può essere difficile capire cosa si applica al tuo caso e cosa no.
Questo problema è aggravato da stronzi persone che scrivono guide con titoli clickbait come “Compila un kernel Nethunter per QUALSIASI dispositivo Android!” o con false promesse come “Impara a compilare un kernel Nethunter in dieci minuti!” È anche una sfortunata realtà di Internet nel 2025 che molti idioti pensino che ChatGPT o altri grandi modelli linguistici abbiano risposte autorevoli alle loro domande, quando tutto ciò che questi modelli hanno davvero sono informazioni recuperate dai suddetti stronzi.
Scrivo questa guida nel modo più approfondito e onesto possibile. Tuttavia, non è pensata per essere l'unico documento che dovrai leggere per questo processo: sicuramente avrai domande a cui questo documento non può rispondere. Vorrei incoraggiarti a cercare le risposte a queste domande nella documentazione software pertinente e NON su YouTube o da ChatGPT.
Prima di iniziare QUALSIASI parte di questo processo, dovresti GIÀ avere:
apt update && apt upgrade -y (facoltativo: aggiunti metapacchetti)Per completare questo processo, avrai bisogno di:
cd, rm, ls, mkdir, find, diff, grep, ecc.)vim per i ragazzi fighi, altrimenti nano)build-devel sulle distro basate su Arch, build-essential su quelle basate su Debian) – ti consiglio anche di installare Perl + Python3 poiché alcuni makefile del kernel li richiedonoSarà possibile per il mio dispositivo?
Il kernel Linux è concesso in licenza GNU General Public License 2.0, che è una licenza copyleft. Ciò significa che il codice sorgente del kernel Linux è distribuito liberamente e puoi modificare il codice sorgente come desideri (come ha fatto ogni produttore Android), TUTTAVIA, il codice sorgente risultante deve ANCHE essere distribuito liberamente.
Con sorpresa di nessuno, molte delle gigantesche corporation che usano codice con licenza GPL sfoggiano i termini di questa licenza. O rifiutano di distribuire il loro codice sorgente o ne rilasciano solo una parte (di solito rotta, obsoleta e con blob binari incorporati). Se non c'è codice sorgente disponibile per il kernel del tuo dispositivo, non c'è modo di creare un kernel Nethunter per esso.
La tua capacità di sbloccare il bootloader e installare una ROM personalizzata dipende anche in gran parte dai capricci del produttore del tuo dispositivo. Anche se consentono lo sblocco del bootloader e sei stato in grado di fare il root del telefono con Magisk, se non pubblicano i device tree, probabilmente non ci sono ROM personalizzate per il tuo dispositivo. In questo caso, è estremamente dubbio che il codice sorgente del kernel che hanno pubblicato (se presente) abbia ricevuto manutenzione dalla sua pubblicazione, o che compili anche senza modifiche. Se non vedi nessun altro che mantiene qualcosa (kernel, ROM, recovery) per il tuo dispositivo, allora sarà difficile, se non impossibile, trasformare quel dispositivo in un Nethunter completo.
Una nota sulle versioni del kernel
Immaginiamo che ci siano ROM personalizzate/kernel/recovery aggiornati e mantenuti regolarmente per il tuo dispositivo, ma semplicemente nessun kernel Nethunter. In questo caso, dovresti essere in grado di completare questo processo, ma il processo varierà a seconda della versione del kernel Linux utilizzata dal tuo dispositivo.
Le informazioni in questa guida si basano sulla mia esperienza di modifica dei kernel 4.14.x. Ci sono guide più vecchie che parlano dell'uso di toolchain GCC (invece di LLVM/clang, come useremo noi) che si applicano ai kernel 3.x. Se il tuo dispositivo usa una versione 5.x/6.x del kernel Linux, le informazioni in questa guida non saranno sufficienti per completare questo processo. Il metodo di compilazione Android cambia continuamente e dovresti cercare una guida che copra i kernel GKI e l'uso di Bazel/Kleaf.
Un buon modo per trovare repository che contengono il sorgente del kernel per il tuo dispositivo è usare il suo nome in codice. Ogni Android ne ha uno, anche se alcuni produttori (es. OnePlus) si divertono un po' di più di altri (es. Samsung). Il nome in codice del mio Xiaomi Poco X3 NFC è "surya", mentre quello del mio Samsung A51 è "SM-A515F". Tipicamente, i repository del sorgente del kernel seguono la convenzione di denominazione
android_kernel_MANUFACTURER_CODENAME
dove il produttore è la società madre, cioè android_kernel_xiaomi_surya, non android_kernel_poco_surya.
Tuttavia, potrebbero esserci anche repository basati sul SoC (system-on-a-chip) del tuo dispositivo, a volte "unificati" per includere file sorgente per altri dispositivi con lo stesso SoC. Questo è il caso del Samsung che ho menzionato, il cui repository sorgente si chiama android_kernel_samsung_exynos9611. Dai un'occhiata su github/gitlab e vedi cosa riesci a trovare.
Ai fini di questa guida, userò l'ultima LineageOS 22.2 (compilata il 2025-08-04) su surya, quindi vorrò clonare il sorgente del kernel dal repository LineageOS. Ma prima di farlo, voglio copiare due file dal mio dispositivo al computer che userò per compilare il kernel: /proc/config.gz e /proc/version.
Potrei copiare il primo file, /proc/config.gz, in /sdcard, recuperarlo dal dispositivo con ADB, decomprimerlo con gunzip e rinominarlo. Ma sembrano un sacco di passaggi, quindi quello che ho fatto invece è stato questo:

Poi, sul dispositivo stesso, ho eseguito (come root)

Cosa sta succedendo qui?
Sul mio laptop: nc (netcat) -l (ascolta le connessioni in entrata) -p (porta) 4545 (in realtà potrebbe essere qualsiasi numero tra 1024-65535, ma di solito uso 4545) > (scrivi su file) surya-defconfig-lineageos22.2-20250804 (nome file descrittivo) < (input da file) /dev/null (dispositivo nullo – questo garantisce che se tocco la tastiera, non invii la sequenza di tasti nel file che sto ricevendo, rischiando di rovinarlo).
Sul telefono: zcat (come il comando cat per concatenare ma per file gzippati) /proc/config.gz (la configurazione del kernel con cui è stato compilato il kernel attualmente in esecuzione) | (invia l'output di quel processo come input al processo successivo) nc (di nuovo netcat) 192.168.1.42 (l'indirizzo IP locale del mio laptop) 4545 (porta impostata prima)
Sebbene questo dovrebbe darti il file .config che è stato usato per compilare il kernel attualmente in esecuzione, non è sempre così. Alcuni dispositivi più moderni/versioni di ROM più recenti si rifiuteranno di avviarsi se la configurazione salvata in /proc/config.gz non corrisponde al .config usato per compilare il kernel stock. Fortunatamente, questo è l'unico controllo che avviene (non qualcosa di molto più difficile da aggirare come un checksum SHA256 dell'intero kernel), quindi alcune persone intelligenti hanno escogitato un modo per falsificare il file in /proc/config.gz per corrispondere al kernel stock, nonostante le loro modifiche. Se non sei sicuro che il file sul tuo dispositivo sia reale o falsificato, puoi eseguire zcat /proc/config.gz | head e poi uname -r. Se i numeri di release non corrispondono, allora il file in /proc è stato falsificato. In quel caso, anche se puoi comunque procedere con questa guida, potresti voler eseguire diff per confrontare la configurazione estratta con alcuni dei file che trovi nella directory arch/arm64/configs del tuo sorgente kernel.
Per quanto riguarda /proc/version, potrebbe non essere così necessario inviare quel file, dato che tutto ciò di cui abbiamo davvero bisogno è l'informazione su quale versione di clang/ld.lld è stata usata per compilarlo. Quindi possiamo semplicemente eseguire cat /proc/version e dare un'occhiata:

Uh oh! Sembra che chiunque abbia compilato questo kernel abbia fatto un piccolo “oopsie” e il suo Makefile abbia registrato tutti i -CFLAGS eseguiti con clang, ma non la versione di Clang. Tuttavia, possiamo vedere che hanno usato una toolchain Android precompilata e che hanno usato ld.lld versione 19.0.1.
Ecco un'immagine leggermente più utile. Il primo output è di /proc/version prima di modificare, compilare e installare un nuovo kernel su Samsung A51. Il secondo output è di /proc/version attuale.

Noti qualcosa? (No, non il mio bizzarro nome utente e hostname).
Il trucco migliore per scegliere una toolchain da usare è usare la toolchain ESATTA che ha compilato il kernel attualmente in esecuzione.
In questo caso, era Neutron clang 18.0.0git, che è stato abbastanza facile da trovare:

E guarda un po', gli md5sum corrispondono e tutto il resto.
Tanto per divertimento, diamo una rapida occhiata alla stringa /proc/version di un dispositivo considerevolmente più vecchio, Samsung J7 (2016), nome in codice j7xelte:

Questo è un dispositivo abbastanza vecchio da usare ancora toolchain GCC per compilare il kernel.
Ma quando cerco "gcc version 4.9.x 20150123 prerelease", trovo due repository:

Quindi quale dovrei scaricare?
La risposta: entrambi. GCC è diverso da Clang in quanto, quando si compilano compilatori/binutils/linker/ecc. per la cross-compilazione, richiede che una toolchain separata venga compilata per ogni "target triple". La target triple (presumibilmente) assume il formato
machine-vendor-operating_system
Ma come vedremo, questa "regola" ha un milione di eccezioni. Ma cominciamo con "machine".
Nella sezione "avrai bisogno" di questo documento, ho detto che serviva un computer a 64 bit con processore Intel o AMD con GNU/Linux. Questo perché le toolchain che useremo sono compilate per essere eseguite su x86_64-linux-gnu.
Tuttavia, queste toolchain sono cross-compiler, il che significa che il codice macchina che generano dai file sorgente C non verrà eseguito su quel computer, ma su uno diverso con la propria target triple.
Aarch64, nota anche come arm64, è l'architettura usata da quasi tutti i dispositivi Android. Arm, senza il "64", si riferisce alle implementazioni a 32 bit dei chip ARM. La maggior parte dei kernel Android è compilata usando sia una triple aarch64 che arm, per fornire retrocompatibilità con il software a 32 bit.
Passiamo alla parte successiva: "Linux". Si spiega da sé. È un kernel Linux.
Ma l'ultima parte di queste "triple" vale la pena di essere spiegata, almeno brevemente, perché è un tale pasticcio contorto e ogni compilatore che usa le "triple" (GCC, Rust, Go, LLVM) lo fa in modo leggermente diverso. "Android", il primo esempio, ha senso, ma cos'è "androideabi"? EABI sta per "embedded application binary interface", ma non devi preoccuparti troppo di questo – consideriamo semplicemente EABI come il terzo valore "base". Vedrai anche "gnueabi", che ora ha un po' più senso – l'implementazione GNU di EABI, giusto? (Quello a cui ci si riferisce davvero è la libreria C di GNU, glibc, motivo per cui vedrai anche triple come arm-linux-musleabi quando compili contro una libreria C alternativa come musl). Potresti anche vedere "gnueabihf". HF sta per "hard float" (virgola mobile hardware), e se vuoi sapere come ARM ha implementato una soluzione on-chip per le operazioni in virgola mobile, vai a leggere un articolo di Wikipedia.
Ecco cosa dobbiamo sapere:
Se si usa una toolchain LLVM, dichiareremo la nostra intenzione di cross-compilare impostando CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi- (così, con il - finale) sulla riga di comando.
Se si compila per un dispositivo molto vecchio e quindi si usa una toolchain GCC, avremo bisogno di due set di file, con prefissi di triple diverse. Questi potrebbero essere gli stessi valori dell'esempio LLVM, o potrebbero essere diversi, come nelle toolchain per j7xelte.
Ma PERCHÉ ci sono così tanti modi per scrivere la stessa cosa? i386, i686, 386, i32, i64, x86, x64, x86_64, amd64 -- che possibile ragione ci può essere per una tale variazione?!
Fumetto pertinente da xkcd:

Tornando all'esempio che compilerò oggi (surya), mi è capitato di salvare le informazioni /proc/version da un altro kernel, che diceva:

Questo è più o meno come dovrebbe apparire, con il link, i checksum, le versioni di compilatore/linker, ecc. E dato che le versioni di clang e LLD qui erano entrambe 17.0.3 e il /proc/version malconcio che abbiamo dalla LineageOS attuale mostra LLD 19.0.3, penso che sia logico cercare una toolchain che abbia 19.0.3 per entrambi.
Dopo circa tre minuti di ricerca, ho trovato un repository che possiamo clonare come sottomodulo (per rendere più facile avere una build riproducibile) qui: https://gitlab.com/kei-space/clang/r536225/ Quella toolchain si è rivelata avere problemi seri, quindi sono andato con Neutron Clang 19. (Torneremo su questo).
Quindi abbiamo la nostra sorgente e la nostra toolchain pronte da clonare, il che ci porta a:
Ho deciso di creare un nuovo utente per questo tutorial, soprattutto per poter usare gh auth login ed eseguire i commit senza farli accidentalmente sul mio account github principale. Ma per farlo, ho dovuto creare un account (in un browser), configurare un nuovo utente, generare chiavi SSH per loro…

Copia .ssh/id_ed25519.pub in GitHub, poi esegui gh di nuovo nel terminale

E poi sono a posto

…quasi. Devo ancora fare il fork del repository nel browser,

poi inizializzarlo/clonarlo nel terminale.

Quindi, una volta che tutto è pronto (sorgenti aggiornate, origin impostato, ecc.) possiamo iniziare a clonare i sottomoduli.

La sintassi è git submodule add URL directory/

Ricorda, per una cronologia dei commit molto pulita vogliamo eseguire git add . e git commit -a dopo ogni modifica.

Non eseguirò ancora git push, ma quando alla fine lo farà, aggiornerà tutti i commit.
Qui è dove probabilmente ti aspetti che la guida parli di apportare modifiche al sorgente del kernel per aggiungere il supporto Nethunter. Sta arrivando – presto. PRIMA, però, vediamo come il sorgente non modificato compila con la nostra toolchain e configurazione.

Quella config del kernel attualmente in esecuzione deve essere copiata nella directory del sorgente del kernel, ma dato che useremo out/ per i nostri binari compilati devo copiarla anche lì. Devo anche aggiungere alla mia variabile PATH la directory bin/ della toolchain. Potrei scrivere export PATH=/home/build_user/android_kernel_xiaomi_surya/toolchain/bin:$PATH ma un modo più semplice è semplicemente fare cd in quella directory e poi eseguire export PATH=$(pwd):$PATH. $() si espande al risultato di un comando che contiene, e pwd elenca l'intero percorso della directory di lavoro corrente.
Ho anche elencato il contenuto della directory bin/ della toolchain così puoi vedere come i binutils LLVM hanno il loro prefisso. Idealmente, il Makefile contiene un'istruzione dove se dichiaro LLVM=1, imposta automaticamente AR=llvm-ar, AS=llvm-as, ecc. Quindi vediamo cosa c'è nel Makefile.

Eccellente! Posso semplicemente dichiarare LLVM=1 e non dover dichiarare individualmente il resto… più o meno. Devo anche usare l'assembler LLVM, ma questo ha la sua dichiarazione, LLVM_IAS:

Quindi ora tutto ciò che dovrò dichiarare è ARCH=arm64 LLVM=1 LLVM_IAS=1 AS=llvm-as O=out CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi-. Potrebbe sembrare tanto, ma è molto meno che dichiarare ogni singolo binutil.
Quindi eseguiamo il nostro comando per aprire la configurazione….
Aspetta. Sembra che questa toolchain abbia qualche problema. Quindi ho deciso di deinitare il sottomodulo e invece prendere Neutron Clang 19.0.0 da qui, e lo scaricherò con wget

Poi estraggo in una directory toolchain/ appena creata (dimenticando all'inizio la sintassi per estrarre i file .tar.zst)

E poi aggiungo questa directory al file .gitignore.
Ora quando eseguo questo:

Funziona, aprendo il menu nconfig:

Molti tutorial ti diranno di usare menuconfig, ma io preferisco nconfig perché 1) ha un aspetto migliore 2) non ha la stessa tendenza di menuconfig a non caricarsi perché non riesce a trovare le librerie ncurses che hai già installato. In ogni caso, questo è solo un kernel di test, quindi possiamo caricare .config e salvarlo (di nuovo come .config) e per ora abbiamo finito.
E ora proviamo a compilare Image.gz, e…

Il nostro primo errore! Evviva!
Secondo questo, questo è dovuto al fatto che un aggiornamento di Arch ha rotto qualcosa.
Anche se Arch toglie, Arch dà anche, in questo caso sotto forma del pacchetto AUR libxml-legacy. Quindi l'ho installato, ho eseguito di nuovo make, e questa volta:

Complimenti ai manutentori di LineageOS, perché l'intero kernel è stato compilato con un solo warning:

Quindi ora in out/arch/arm64/boot/ possiamo trovare Image.gz. Ma come potremmo flashare questo sul nostro dispositivo?
Dobbiamo creare uno zip AnyKernel3.
Ci sono due modi per farlo:
Image, potrebbe essere la Image.gz che abbiamo creato e nient’altro, potrebbe essere Image.gz-dtb (un’immagine combinata device tree/kernel – oggigiorno sono meno comuni, ma se il tuo dispositivo se ne aspetta una, dovrai abilitare "Build a concatenated Image.gz-dtb" nella configurazione del kernel), oppure potrebbe essere Image.gz, dtbo.img e/o dtb.img.
Ai fini di questa guida, ho scaricato uno dei tanti kernel distribuiti su Telegram con un nome da anime stupido e senza sorgente collegato. Non installate mai uno di questi kernel.
Ma non faremo questo, non preoccupatevi: stiamo solo prendendo in prestito la loro configurazione dello zip AnyKernel. Quindi rinomino ed estraggo il file

Poi ho modificato lo script anykernel.sh per cambiare anche la stringa del nome del kernel. Ora sovrascriviamo la Image.gz di quello zip con la nostra nuova

Usare zip -f (per “freshen”) sostituirà semplicemente il file all’interno con la nuova versione. 0 sta per compressione zero.
Vediamo se riesco a flashare questo kernel e se si avvia, ma prima:

È molto più facile tenere traccia degli zip del kernel quando includi stringhe di data e ora.

Tuttavia, per amor di completezza (e per dipendere il meno possibile dai kernel di Telegram), ti spiegherò come creare i tuoi file dtb.img e/o dtbo.img, dato che la documentazione al riguardo è terribilmente inadeguata.
Esistono due programmi AOSP per questo scopo. Uno, mkdtboimg, è scritto in Python, il che rende facile semplicemente scaricare ed eseguire mkdtboimg.py dal sito ufficiale di AOSP. Tuttavia, potresti aver bisogno anche dell’altro, mkdtimg, che è scritto in C e distribuito senza Makefile. Secondo la documentazione, i file Android.bp sono sufficienti -- devi solo fare il checkout dell’intero codice AOSP per poter eseguire i comandi elencati lì. Trovo tutto ciò completamente assurdo, quindi ho preso il Makefile che qualcun altro aveva creato molto tempo fa per compilare questo strumento da solo, ho aggiornato i file sorgente con l’ultima versione e poi l’ho compilato come static-PIE contro Musl. Puoi scaricare questo binario (che funzionerà su qualsiasi computer Linux x86_64, come quello che stai usando per compilare il kernel) da qui, oppure compilarlo tu stesso dal codice sorgente.
Ora arriva la parte spinosa: i file .dtbo prodotti durante una compilazione del kernel non saranno convertibili in file dtb.img/dtbo.img senza un piccolo sforzo extra. Android richiede che la chiamata a dtc includa il flag -a 64. Dato che stiamo già chiamando DTC_EXT=/usr/bin/dtc per forzare il Makefile a usare il nostro bellissimo DTC aggiornato dal gestore pacchetti e non quello rotto presente in molti kernel, non è difficile semplicemente mettere quel comando tra apici singoli e aggiungere il flag. Puoi semplicemente passare DTC_EXT='/usr/bin/dtc -a 64'. Nel mio caso, però, mi piace creare (e testare) script build.sh per tutti i kernel che mantengo, così che anche senza leggere questa guida chiunque, per quanto n00b, possa compilare il proprio da sorgente. Mentre lottavo con strati e strati di logica bash tra apici singoli e doppi, ho trovato una soluzione semplice, seppur poco elegante, che garantisce che DTC venga chiamato con il flag corretto: uno script wrapper.
Ho semplicemente creato un file eseguibile chiamato dtc nella directory principale del mio kernel, contenente le seguenti righe:
#!/bin/sh
exec /usr/bin/dtc -a 64 $@
Poi ho puntato DTC_EXT= a quel file, e questo ha risolto tutto.
Ti starai chiedendo: “Quali file .dtbo? Le mie compilazioni del kernel non li generano mai!” In tal caso dovresti controllare che questo simbolo del kernel sia abilitato:

Allora, come si usano questi strumenti? La prima cosa che ho fatto è stata analizzare i file dtb.img e dtbo.img trovati in altri zip del kernel per vedere che tipo di file fossero. (Lo so, lo so, non vogliamo dipendere dai kernel strani della scena delle ROM custom per i nostri, ma vale la pena controllare). Il comando file dtb.img ha restituito:
dtb.img: Device Tree Blob version 17, size=345849, boot CPU=0, string block size=31481, DT structure block size=314312
che è (quasi) esattamente lo stesso risultato che ottengo quando eseguo 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
Quella piccola differenza mi preoccupava, finché non ho eseguito diff <(strings dtb.img) <(strings ../arch/arm64/boot/dts/qcom/sdmmagpie.dtb) e ho scoperto che contenevano esattamente le stesse cose. Quindi ora potevo tranquillamente supporre che creare la mia dtb.img fosse solo una questione di copiare sdmmagpie.dtb e cambiarne il nome.
Quanto a dtbo.img, da file non riceviamo molto aiuto:
dtbo.img: data
Ma è qui che possiamo usare mkdtimg o mkdtboimg.py per analizzarla. Quando eseguo mkdtimg dump dtbo.img, ottengo:

Quindi so che quando ne creo una mia, devo passare uno tra
mkdtimg create dtbo.img --page_size=4096 ../arch/arm64/boot/dts/qcom/sdmmagpie-idp-overlay.dtbo
oppure
mkdtboimg create --page_size=4096 dtbo.img ../arch/arm64/boot/dts/qcom/sdmmagpie-idp-overlay.dtbo
Entrambi i comandi producono file identici. Puoi anche eseguire mkdtimg dump dtbo.img in seguito e confrontare i valori con l’altro file. Se devi includere più di un file .dtbo nella tua immagine, ti basta aggiungere il suo percorso alla fine di uno dei due comandi.
Ora torniamo al kernel di test che abbiamo creato. La buona notizia è che si è flashato senza problemi; la cattiva è che dovrò sistemare quel Makefile che genera un /proc/version così brutto.
Ma può aspettare. Ora, finalmente, siamo arrivati a:
È ora di aggiungere alcuni sottomoduli. Prima questo, che include istruzioni molto facili da seguire. (Nota: ora contiene anche i simboli del kernel del sottosistema CAN, dato che la mia pull request per aggiungerli è stata accettata, anche se non lo vedrai negli screenshot qui sotto).

E ora, quando eseguo di nuovo make nconfig (stesso comando di prima)

abbiamo questa splendida nuova opzione

che abiliterà tutte queste cose. Selezionala, salva come .config – ma attenzione: la salverà in out/.config e noi elimineremo l’intera directory prima di ricompilare. Quindi, una volta usciti da nconfig, copia quel file nella directory dei sorgenti del kernel.
Ora è il momento di applicare patch ad alcuni file sorgente, quindi aggiungiamo il repo degli script di build di Nethunter come sottomodulo:

Facciamo cd nella nuova directory ed eseguiamo ./build.sh, poi scegliamo l’opzione 4: Apply Nethunter kernel patches.

Se ricevi messaggi che dicono “the test run was completed with errors,” NON applicare la patch. Altrimenti, fai pure. Nel mio caso ho applicato le patch 4, 5 e 8.
Ora che abbiamo fatto delle modifiche, torniamo alla directory principale dei sorgenti del kernel e committiamole.

A questo punto potresti semplicemente ricompilare il kernel e il gioco è fatto. Ma io non mi accontento: voglio includere il supporto per un sacco di cose extra, in particolare:

Dovremo modificare il Kconfig e il Makefile in drivers/net/wireless/realtek per far sì che la configurazione rilevi questi driver appena aggiunti, ma anche:

Assicurati di impostare la piattaforma nel rtl8812au/Makefile su ANDROID_ARM64 (così come per rtl8188eus).
Vale anche la pena ricontrollare il Kconfig nei driver appena aggiunti per vedere come si chiama l’opzione di configurazione:

Ora so che devo riferirmi ad essa come 88XXAU nel Makefile di un livello più sopra.

Fortunatamente, il Kconfig viene semplicemente incluso così:

Dovrò modificare di nuovo questi file dopo aver aggiunto anche rtl88x2bu e il ramo ARM di rtl8188fu. (E a quanto pare, l’opzione di configurazione di rtl88x2bu si chiama RTL8822BU, motivo per cui vale sempre la pena controllare).
Ora passiamo ai driver MediaTek backportati. Usando questo commit come guida, ho portato con successo questi driver su due dispositivi diversi con kernel 4.14.x. (Vedi perché la storia dei commit è importante?) Ma prima ci serve la directory mt76 con tutti i suoi file.
Invece di dover clonare un kernel 4.19 ed estrarne i file, per poi applicare le patch necessarie a quei file nella tua nuova copia, puoi semplicemente aggiungere https://github.com/akabul0us/mt76.git come sottomodulo. Poi modifica il Makefile e il Kconfig nella directory drivers/net/wireless/mediatek:

Aggiungendo questo repo con le patch del commit menzionato in precedenza già applicate ai loro sorgenti, possiamo saltare direttamente alle modifiche che dobbiamo fare agli altri file del kernel. Il primo è questo:

Ma a quanto pare il nostro sorgente del kernel ha già questa struct:

Quindi passiamo al file successivo da modificare, include/linux/overflow.h. Questo ha alcune modifiche, ma dato che sono abbastanza chiare da leggere nel commit originale, ti risparmio altri screenshot. Anche include/linux/skbuff.h e include/linux/scatterplot.h hanno modifiche, ma nessuna è necessaria per include/net/cfg80211.h. Le modifiche necessarie a include/net/mac80211.h sono minori: basta inserire RX_ENC_HE come ultima riga dentro enum mac80211_rx_encoding { } e aggiungere u8 vht_flag; in struct ieee80211_rx_status { }. Il file net/wireless/of.c esiste già ed è identico a quello del commit che stiamo facendo cherry-pick, quindi abbiamo finito lì. (Uff!)
Quanto al supporto Docker, beh, grazie (ancora una volta) a cyberknight777 per questo, possiamo semplicemente copiare e incollare

E ora siamo pronti a fare di nuovo nconfig! …quasi. Prima, fai commit e push delle modifiche, poi rm -rf out/ (assicurandoti di aver salvato il tuo .config fuori da lì), mkdir -p out, e SOLO DOPO possiamo tornare alla configurazione.

Una nota sui driver USB Realtek fuori-albero che abbiamo aggiunto al kernel: Fanno abbastanza schifo. Se provi a compilarne più di uno inline, otterrai errori in fase di linking. Una soluzione di vecchia data è compilarne uno (1) solo inline e gli altri come moduli. I driver Mediatek, invece, possono essere compilati inline senza problemi.
Alla fine ho abilitato un sacco di altre cose; se vuoi vedere il diff completo l’ho messo qui, ma comunque, compiliamo!

Ottimo inizio: è sempre bello vedere nuovi file oggetto appena aggiunti compilare senza errori né warning.

Questo? Meno bello, ma facile da sistemare. Dobbiamo solo rimuovere -Wno-stringop-overread dal Makefile che lo ha come flag di warning. E già che ci siamo, -Werror è un po’ estremo, non trovi? (Questo flag significa ‘tratta tutti i warning come errori,’ bloccando la compilazione a QUALSIASI intoppo, incluso un flag -W sconosciuto).

Almeno questo è facile da sistemare.

Basta un veloce # davanti a quella riga e siamo pronti a rilanciare make – e questa volta, è arrivato fino in fondo!
Ma dato che ho configurato alcuni driver come moduli, non abbiamo ancora finito. Dobbiamo eseguire make modules, o più precisamente, 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 accidenti, il codice del driver Realtek per rtl8188fu è un disastro totale:

Potrei correggere manualmente ciascuna delle righe che causano questi warning? Certo. Lo farò? No. C’è un motivo se compilo questi driver come moduli e non inline, e incoraggio attivamente tutti a evitare gli adattatori basati su Realtek. Tuttavia:

Almeno hanno compilato con successo. Ma ci torniamo tra un momento. Prima rinfreschiamo il nostro zip del kernel:

(Quasi dimenticavo: questo non è più un kernel “di test”, è un vero kernel Nethunter).
Quanto ai moduli, i file .tar sono davvero la scelta migliore perché preservano tutto dei file che contengono – però preservano anche i percorsi. A meno che non facciamo qualcosa al riguardo, quando estraiamo il nostro tarball dei moduli creeremo un sacco di directory, come drivers/net/wireless/realtek/rtl8188fu/rtl8188fu.ko per esempio, quindi creiamo una directory (e aggiungiamola a .gitignore), copiamoli lì dentro e poi creiamo l’archivio.

Puoi flashare questi come faresti con un kernel?

Questi vanno estratti da qualche parte sul tuo dispositivo. Dico “da qualche parte” perché non importa davvero dove, purché quando esegui insmod /whatever/path/to/whatever.ko il modulo venga caricato. Potresti farlo in /sdcard, andrebbe bene, ma ricorda che io non mi accontento, quindi li estrarrò nel posto “giusto” per questo dispositivo, /vendor/lib/modules. Ovviamente /vendor è montato in sola lettura, quindi prima dovrò avviare una root shell (NON nel terminale Nethunter – quello è una chroot – anche se puoi usare l’app del terminale Nethunter se selezioni “New Session → Root Shell”) ed eseguire mount -o rw,remount /vendor prima di poter fare qualsiasi cosa su quella partizione. Poi cd /vendor/lib/modules; tar xzvf /sdcard/or/wherever/you/saved/the/tarball.tgz; mount -o ro,remount /vendor e hai finito con i moduli.
Se ottieni un errore di spazio insufficiente su quella partizione, puoi anche usare un link simbolico: infila il file, per esempio, in /sdcard/modules, e poi crea un link usando il percorso assoluto. Quindi, se facessimo questo con 88x2bu.ko, eseguiremmo ln -s /storage/emulated/0/modules/88x2bu.ko /vendor/lib/modules/88x2bu.ko.

Fai un ultimo push al tuo repo e, se vuoi, salva il .config che hai usato come nuova defconfig per nethunter. (Questo aiuta davvero chi compila da sorgente).
Funziona? Flasha senza problemi, certo, ma funziona davvero?
Beh, qui è abbastanza tardi, quindi non testerò assolutamente ogni singola funzione adesso, ma andiamo su quella cruciale: modalità monitor/iniezione di pacchetti sui driver che ho aggiunto al kernel. Iniziamo con rtl88x2bu:

Non male, per un driver Realtek.
E ora l’evento principale: mt76x2u:

Questo sì che è un dispositivo per pentesting!
L’ultimo passo è caricare il tuo .zip e .tar.gz su github come release. Poi vai a postarlo su xdaforums, Telegram, Twitter, ovunque pensi che altri utenti dello stesso dispositivo/ROM lo trovino e ne traggano beneficio.
E quando qualche ingrato idiota col culo non lavato risponde al tuo post con “NOW U MAKE KARNEL FOR DEVICE BUTTPHONE 34AC PRO EDITION?!!?”, dagli il link a questa guida e digli di git gud.
Buonanotte a tutti.
--Akabul0us