
Android向けカスタムKali NetHunterカーネルを構築するためのステップバイステップガイド:ソースの取得、ツールチェーンの選択、クロスコンパイル、フラッシュ。
Nethunter デバイスをセットアップしたいほとんどの人にとって最大のハードルは、カーネルの要件です。お使いのデバイスにプリビルド(およびメンテナンス済み)のカーネルが既にあるのでない限り、自分でビルドするように言われるでしょう。このプロセスに関するドキュメントはすでにたくさんありますが、私の経験では、自分のケースに何が当てはまり、何が当てはまらないのかを判断するのは難しいことがあります。
この問題をさらに厄介にしているのは、「Build a Nethunter kernel for ANY Android device!」のようなクリックベイト的なタイトルや、「Learn how to compile a Nethunter kernel in ten minutes!」のような誤った約束をするガイドを書くバカ人たちです。また、2025年のインターネットの残念な現実として、多くの頭の悪い人々が、ChatGPTや他の大規模言語モデルが自分の質問に対して権威ある答えを持っていると思い込んでいますが、それらのモデルが実際に持っているのは、前述のバカたちからスクレイピングした情報にすぎません。
私はこのガイドを、可能な限り徹底的かつ正直に書いています。ただし、これはこのプロセスで読む必要がある唯一のドキュメントであることを意図していません。このドキュメントが答えられない疑問も必ず出てくるでしょう。そうした疑問に対する答えは、該当するソフトウェアのドキュメントで探すことをお勧めします。YouTubeやChatGPTで探すのはやめてください。
このプロセスのいずれかを始める前に、既に以下のことを済ませておく必要があります:
apt update && apt upgrade -y (任意:メタパッケージを追加している)このプロセスを完了するために必要なもの:
cd, rm, ls, mkdir, find, diff, grep, など)vim、それ以外はnano)build-devel、Debian系ではbuild-essential) – また、一部のカーネルMakefileがこれらを必要とするため、Perl + Python3をインストールすることもお勧めします私のデバイスでも可能でしょうか?
Linuxカーネルは、コピーレフトライセンスであるGNU General Public License 2.0の下でライセンスされています。これは、Linuxカーネルのソースコードが自由に配布され、あなたが望むようにソースコードを変更できることを意味します(各Androidメーカーが行っているように)。しかし、その結果得られたソースコードもまた、自由に配布されなければなりません。
誰も驚かないことに、GPLライセンスのコードを使用している巨大企業の多くは、このライセンスの条件を無視しています。彼らはソースコードの配布を拒否するか、一部だけを公開します(通常は壊れていたり、古かったり、インラインのバイナリブロブが含まれています)。お使いのデバイスのカーネル用のソースコードが利用できない場合、そのデバイス用のNethunterカーネルを作成する方法はありません。
ブートローダーのロックを解除してカスタムROMをインストールできるかどうかも、デバイスメーカーの気まぐれに大きく依存します。たとえブートローダーのロック解除を許可し、Magiskでスマートフォンをroot化できたとしても、デバイスツリーを公開していなければ、お使いのデバイス向けのカスタムROMはおそらく存在しません。この場合、彼らが公開したカーネルソースコード(もしあれば)がリリース以降メンテナンスされている可能性は極めて低く、変更なしでもビルドできるかどうかも疑わしいです。お使いのデバイス向けに他の誰も(カーネル、ROM、リカバリを)メンテナンスしていないのなら、そのデバイスを完全なNethunterにするのは、不可能でないにしても困難でしょう。
カーネルバージョンに関する注意
お使いのデバイス向けに定期的に更新・メンテナンスされたカスタムROM/カーネル/リカバリが存在するが、Nethunterカーネルだけは存在しないと想像してみましょう。この場合、このプロセスを完了できるはずですが、そのプロセスはお使いのデバイスが使用するLinuxカーネルのバージョンによって異なります。
このガイドの情報は、4.14.xカーネルを変更した私の経験に基づいています。3.xカーネルに適用される、(これから使用するLLVM/clangではなく)GCCツールチェーンを使用することについて書かれた古いガイドもあります。お使いのデバイスが5.x/6.xバージョンのLinuxカーネルを使用している場合、このガイドの情報だけではこのプロセスを完了するのに不十分です。 Androidのビルド方法は常に変化しているため、GKIカーネルとBazel/Kleafの使用を扱ったガイドを探すべきです。
お使いのデバイスのカーネルソースを含むリポジトリを見つける良い方法は、コードネームを使用することです。すべてのAndroidデバイスにはコードネームがありますが、一部のメーカー(例:OnePlus)は他社(例:Samsung)よりも少し遊び心があります。私のXiaomi Poco X3 NFCのコードネームは「surya」で、私のSamsung A51のコードネームは「SM-A515F」です。通常、カーネルソースのリポジトリは次の命名規則に従います。
android_kernel_MANUFACTURER_CODENAME
ここで、manufacturerは親会社です。つまり、android_kernel_poco_suryaではなくandroid_kernel_xiaomi_suryaです。
ただし、お使いのデバイスのSoC(システム・オン・チップ)に基づくリポジトリもあるかもしれません。同じSoCを持つ他のデバイスのソースファイルを含めるために「統合」されていることもあります。先ほど言及したSamsungがそのケースで、そのソースリポジトリはandroid_kernel_samsung_exynos9611と呼ばれています。github/gitlabを探して、何が見つかるか見てみてください。
このガイドでは、suryaで最新のLineageOS 22.2(2025-08-04ビルド)を使用します。したがって、LineageOSリポジトリからカーネルソースをクローンしたいと思います。ただし、その前に、デバイスからカーネルビルドに使用するコンピュータへ2つのファイル(/proc/config.gzと/proc/version)をコピーしたいと思います。
最初のファイル/proc/config.gzを/sdcardにコピーし、ADBでデバイスからpullし、gunzipして、名前を変更するという方法もあります。しかし、それは多くの手順のように思えるので、代わりに私が行ったのはこれです:

次に、デバイス自体で(rootとして)実行しました

ここで何が起こっているのでしょうか?
ラップトップ側:nc(netcat)-l(受信接続を待ち受ける)-p(ポート)4545(実際には1024〜65535の任意の番号で構いませんが、私はたいてい4545を使います)>(ファイルに書き込む)surya-defconfig-lineageos22.2-20250804(説明的なファイル名)<(ファイルからの入力)/dev/null(ヌルデバイス – これにより、キーボードに触れても、受信しているファイルにキーストロークが送り込まれて壊れるのを防げます)。
スマートフォン側:zcat(連結のためのcatコマンドに似ていますが、gzip圧縮ファイル用)/proc/config.gz(現在実行中のカーネルがビルドされたときのカーネル構成)|(そのプロセスの出力を次のプロセスへの入力として送る)nc(再びnetcat)192.168.1.42(私のラップトップのローカルIPアドレス)4545(先ほど設定したポート)
これにより、現在実行中のカーネルのビルドに使用された.configファイルが得られるはずですが、常にそうとは限りません。一部の新しいデバイス/新しいROMビルドでは、/proc/config.gzに保存されている構成が、ストックカーネルのビルドに使用された.configと一致しない場合、起動を拒否します。幸いなことに、チェックされるのはそれだけです(カーネル全体のSHA256チェックサムのような、もっと破りにくいものではありません)。そのため、賢い人々は、変更を加えているにもかかわらず、/proc/config.gzのファイルをストックカーネルに一致するように偽装する方法を考案しました。デバイスのファイルが本物か偽装かを確認するには、zcat /proc/config.gz | headを実行し、次にuname -rを実行します。リリース番号が一致しない場合は、/proc内のファイルは偽装されています。その場合でもこのガイドを進めることはできますが、抽出したconfigをカーネルソースのarch/arm64/configsディレクトリにあるいくつかのファイルと比較するためにdiffを実行するとよいかもしれません。
/proc/versionについては、そのファイルを送信する必要はあまりありません。実際に必要なのは、コンパイルに使用されたclang/ld.lldのバージョン情報だけだからです。したがって、単にcat /proc/versionを実行して確認するだけで十分です:

おやおや!このカーネルをビルドした人はちょっと「おっと」という感じで、Makefileにclangで実行したすべての-CFLAGSを記録したものの、Clangのバージョンを記録していないようです。ただし、プリビルドのAndroidツールチェーンを使用し、ld.lldバージョン19.0.1を使用したことはわかります。
もう少し役立つ画像を紹介します。最初の出力は、Samsung A51で新しいカーネルを変更・ビルド・インストールする前の/proc/versionからのものです。2番目の出力は現在の/proc/versionからのものです。

何か気づきましたか?(いいえ、私の奇妙なユーザー名とホスト名のことではありません)
使用するツールチェーンを選ぶ最良のコツは、現在実行中のカーネルをコンパイルしたまったく同じツールチェーンを使うことです。
この場合、それはNeutron clang 18.0.0gitでした。見つけるのは非常に簡単でした:

そして見てください、md5sumが一致しています。完璧です。
楽しみのために、かなり古いデバイスであるSamsung J7(2016年)、コードネームj7xelteの/proc/version文字列を少し見てみましょう:

これは、カーネルのコンパイルにまだGCCツールチェーンを使用していた十分に古いデバイスです。
しかし「gcc version 4.9.x 20150123 prerelease」を検索すると、2つのリポジトリが見つかります:

では、どちらをダウンロードすべきでしょうか?
答え:両方です。GCCはClangと異なり、クロスコンパイル用のコンパイラ/binutils/リンカなどをビルドする際、「ターゲットトリプル」ごとに個別のツールチェーンをビルドする必要があります。ターゲットトリプルは(おそらく)次の形式を取ります。
machine-vendor-operating_system
しかし、これから見るように、この「ルール」には無数の例外があります。まずは「machine」から始めましょう。
このドキュメントの「必要なもの」セクションで、GNU/Linuxを実行しているIntelまたはAMDプロセッサを使用する64ビットコンピュータが必要だと言いました。それは、これから使用するツールチェーンがx86_64-linux-gnu上で実行されるようにコンパイルされているからです。
ただし、これらのツールチェーンはクロスコンパイラです。つまり、Cソースコードファイルから生成されたマシンコードはそのコンピュータでは実行されず、独自のターゲットトリプルを持つ別のコンピュータ上で実行されます。
Aarch64(arm64とも呼ばれる)は、ほぼすべてのAndroidデバイスが使用するアーキテクチャです。「64」を付けないArmは、ARMチップの32ビット実装を指します。ほとんどのAndroidカーネルは、32ビットソフトウェアとの後方互換性を提供するために、aarch64とarmの両方のトリプルを使用してコンパイルされています。
次の部分「Linux」に移りましょう。説明不要です。Linuxカーネルです。
しかし、これらの「トリプル」の最後の部分は、少なくとも簡単には説明する価値があります。なぜなら、それは非常に複雑で混乱を招くものであり、「トリプル」を使用する各コンパイラ(GCC、Rust、Go、LLVM)は、少しずつ異なる方法で使用するからです。最初の例である「Android」は理にかなっていますが、「androideabi」とは何でしょうか? EABIは「embedded application binary interface(組み込みアプリケーション・バイナリ・インターフェース)」の略ですが、それについてあまり心配する必要はありません。EABIを3番目の値の「基本」と考えましょう。「gnueabi」も目にするでしょうが、これで少し理解しやすくなりました。EABIのGNU実装ですよね?(これが実際に指しているのはGNUのCライブラリであるglibcです。そのため、muslのような代替Cライブラリに対してビルドする場合、arm-linux-musleabiのようなトリプルも見かけるのです)。「gnueabihf」も見かけるかもしれません。HFは「hard float」の略で、ARMが浮動小数点整数演算用のオンチップソリューションをどのように実装したかについて知りたければ、Wikipediaの記事を読んでください。
私たちが知る必要があるのは次のことです:
LLVMツールチェーンを使用する場合、コマンドラインでCROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi-を設定して、クロスコンパイルする意図を宣言します(このように、末尾に-を付けます)。
非常に古いデバイス向けにコンパイルするため、GCCツールチェーンを使用する場合、異なるトリプルをプレフィックスとする2セットのファイルが必要になります。これらはLLVMの例と同じ値かもしれませんし、j7xelteのツールチェーンのように異なるかもしれません。
しかし、なぜ同じものを書く方法がこれほど多いのでしょうか? i386、i686、386、i32、i64、x86、x64、x86_64、amd64 -- こんなに多様な理由があり得るのでしょうか?!
関連するxkcdの漫画:

今日コンパイルする例(surya)に戻ると、たまたま別のカーネルから/proc/versionの情報を保存していました。それには次のように書かれていました:

これがおおよそあるべき姿です。リンク、チェックサム、コンパイラ/リンカのバージョンなどが含まれています。ここでのclangとLLDのバージョンは両方とも17.0.3で、現在のLineageOSから取得した壊れた/proc/versionにはLLD 19.0.3と表示されているので、両方とも19.0.3のツールチェーンを探すのが合理的だと思います。
約3分の検索の後、サブモジュールとしてクローンできるリポジトリ(再現可能なビルドを容易にするため)をここで見つけました:https://gitlab.com/kei-space/clang/r536225/ そのツールチェーンには深刻な問題があることが判明したため、Neutron Clang 19を使うことにしました。(これについては後で戻ります)。
これでソースとツールチェーンをクローンする準備ができました。次のセクションに進みます:
このチュートリアル用に新しいユーザーを作ることにしました。主に、gh auth loginを使用して、誤ってメインのGitHubアカウントにコミットすることなくコミットを実行できるようにするためです。しかし、そのためには(ブラウザで)アカウントを作成し、新しいユーザーをセットアップし、彼らのSSHキーを生成する必要がありました…

.ssh/id_ed25519.pubをGitHubにコピーし、ターミナルに戻ってghを実行します

これで準備完了です

…もう少しです。ブラウザでリポジトリをフォークする必要があります。

次に、ターミナルでinit/cloneします。

すべての準備ができたら(ソースが最新で、originが設定されているなど)、サブモジュールのクローンを開始できます。

構文はgit submodule add URL directory/です。

非常にクリーンなコミット履歴のために、変更のたびにgit add .とgit commit -aを実行したいことに注意してください。

まだgit pushは実行しませんが、最終的に実行すると、すべてのコミットが更新されます。
ここで、Nethunterサポートを追加するためにカーネルソースを変更することについてガイドが語り始めるのを期待しているでしょう。それはすぐに来ます。しかし、まずは変更していないソースが、私たちのツールチェーンと構成でどのようにコンパイルされるかを見てみましょう。

現在実行中のカーネルからのそのconfigをカーネルソースディレクトリにコピーする必要がありますが、コンパイル済みバイナリにout/を使う予定なので、そこにもコピーする必要があります。また、PATH変数にツールチェーンのbin/ディレクトリを追加する必要があります。export PATH=/home/build_user/android_kernel_xiaomi_surya/toolchain/bin:$PATHと書くこともできますが、より簡単な方法は、単にそのディレクトリにcdしてからexport PATH=$(pwd):$PATHを実行することです。$()はそれが含むコマンドの結果に展開され、pwdは現在の作業ディレクトリへの完全なパスを表示します。
ツールチェーンのbin/ディレクトリの内容もリストしました。LLVM binutilsが独自のプレフィックスを持っているのがわかるでしょう。理想的には、MakefileにLLVM=1を宣言すると自動的にAR=llvm-ar、AS=llvm-asなどが設定されるという指示があります。それでは、Makefileの中身を見てみましょう。

素晴らしい!単にLLVM=1を宣言すれば、残りを個別に宣言する必要はありません…おおむね。また、LLVMアセンブラを使用する必要がありますが、それには独自の宣言LLVM_IASがあります:

つまり、宣言する必要があるのはARCH=arm64 LLVM=1 LLVM_IAS=1 AS=llvm-as O=out CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi-だけです。多く見えるかもしれませんが、個々のbinutilをそれぞれ宣言するよりははるかに少ないです。
それでは、構成を開くためのコマンドを実行しましょう…。
待ってください。このツールチェーンにはいくつか問題があるようです。そこで、サブモジュールをdeinitし、代わりにNeutron Clang 19.0.0をここから取得することにしました。これをwgetでダウンロードします。

次に、新しく作成したtoolchain/ディレクトリに展開します(最初は.tar.zstファイルの展開構文を忘れていました)

そして、このディレクトリを.gitignoreファイルに追加します。
これを実行すると:

うまくいき、nconfigメニューが開きます:

多くのチュートリアルはmenuconfigを使うように言うでしょうが、私はnconfigの方が好きです。なぜなら、1) 見た目がより良い、2) menuconfigのように、既にインストールしたncursesライブラリを見つけられずに読み込まれないという傾向がないからです。いずれにしても、これは単なるテストカーネルなので、.configを読み込んで(再び.configとして)保存すれば、今のところは完了です。
そしてImage.gzをビルドしてみます…

最初のエラーです!やったー!
これによると、Archのアップデートが何かを壊したためです。
Archは奪いますが、Archは与えもします。この場合はAURパッケージlibxml-legacyという形で与えてくれました。それでそれをインストールし、もう一度makeを実行したところ、今回は:

LineageOSのメンテナーの皆さんに敬意を表します。カーネル全体がわずか1つの警告だけでビルドできました:

これでout/arch/arm64/boot/内にImage.gzがあります。しかし、これをデバイスにどうやってフラッシュするのでしょうか?
AnyKernel3のzipを作成する必要があります。
これには2つの方法があります:
Imageという非圧縮イメージの場合もあれば、作成したImage.gzだけで済む場合もあり、Image.gz-dtb(デバイスツリーとカーネルを結合したイメージ。最近ではあまり見かけませんが、お使いのデバイスがこれを要求する場合、カーネル設定で "Build a concatenated Image.gz-dtb" を有効にする必要があります)、あるいはImage.gz、dtbo.img、dtb.imgの組み合わせかもしれません。
このガイドの目的のため、テレグラムで配布されている、アニメのバカげた名前が付けられ、ソースがリンクされていない多数のカーネルのうちの1つをダウンロードしました。そのようなカーネルは絶対にインストールしないでください。
しかし、私たちはそんなことをしません。心配しないでください。ただ、彼らのAnyKernel zip設定を借りるだけです。そこでファイル名を変更して解凍します。

そして、カーネル名の文字列も変更するためにanykernel.shスクリプトを編集しました。次に、そのzip内のImage.gzを新しいもので上書きしましょう。

zip -f("freshen"の意味)を使うと、内部のファイルが新しいバージョンに置き換わるだけです。0は圧縮率ゼロを意味します。
このカーネルをフラッシュできるか、起動するかを見てみましょう。ただし、その前に:

カーネルzipを管理するには、時刻と日付の文字列を含めるとはるかに簡単です。

ただし、徹底を期すため(そしてテレグラムのカーネルにできるだけ依存しないため)に、自分でdtb.imgやdtbo.imgファイルを作る方法を説明します。これに関するドキュメントはひどく不十分なので。
この目的のために存在するAOSPプログラムが2つあります。1つはmkdtboimgで、Pythonで書かれているため、公式AOSPウェブサイトからmkdtboimg.pyをダウンロードして実行するだけで簡単に使えます。ただし、もう1つのmkdtimgも必要になるかもしれません。Cで書かれていてMakefileなしで配布されています。ドキュメントによると、Android.bpファイルで十分であり、AOSPコード全体をチェックアウトして、そこに記載されているコマンドを実行するだけです。私はこれは完全に狂っていると思うので、ずいぶん前に誰かがこのツールを単体でビルドするために作ったMakefileを取得し、ソースファイルを最新版に更新し、Muslに対してstatic-PIEビルドしました。このバイナリ(カーネルをビルドしているあなたが使っているような、あらゆるx86_64 Linuxコンピュータで動作します)はここからダウンロードできます。また、ソースコードから自分でビルドすることもできます。
ここからが厄介な部分です。カーネルビルド中に生成される.dtboファイルは、少し余分な作業をしない限りdtb.img/dtbo.imgファイルに変換できません。Androidでは、dtcの呼び出しに-a 64フラグを含める必要があります。Makefileに、多くのカーネルにある壊れたDTCではなく、パッケージマネージャから入手した新しいDTCを使わせるために、すでにDTC_EXT=/usr/bin/dtcを呼び出しているので、そのコマンドを単一引用符で囲んでフラグを追加するのは難しくありません。単にDTC_EXT='/usr/bin/dtc -a 64'を渡せばいいのです。ただ、私の場合、管理しているすべてのカーネルについてbuild.shスクリプトを作成(およびテスト)したいので、このガイドを読まなくても、どんな初心者でもソースからビルドできるようにしています。シングルクォートとダブルクォートのbashロジックが何層にも重なって苦労したとき、私はシンプルで(不格好かもしれませんが)確実にDTCが正しいフラグで呼び出されるようにする解決策、つまりラッパースクリプトを見つけました。
カーネルのトップレベルディレクトリに、dtcという実行可能ファイルを作成し、次の行を含めました。
#!/bin/sh
exec /usr/bin/dtc -a 64 $@
そして、DTC_EXT=をそのファイルに指定したところ、うまくいきました。
「何の.dtboファイル? 私のカーネルビルドではそんなものは生成されない!」と思うかもしれません。その場合は、このカーネルシンボルが有効になっているか確認してください。

では、これらのツールをどう使うのでしょうか。最初にやったことは、他のカーネルzipに入っていたdtb.imgとdtbo.imgファイルを調べて、どんな種類のファイルなのかを確認することでした。(分かってます、分かってます。私たちは自分のカーネルを、奇妙なカスタムROM界隈のカーネルに依存させたくはありません。しかし、これは確認する価値があります)。file dtb.imgコマンドは次のように返しました。
dtb.img: Device Tree Blob version 17, size=345849, boot CPU=0, string block size=31481, DT structure block size=314312
これは、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
そのわずかな違いが気になっていましたが、diff <(strings dtb.img) <(strings ../arch/arm64/boot/dts/qcom/sdmmagpie.dtb)を実行して、まったく同じものが含まれていることを確認しました。そこで、自分のdtb.imgを作成するのは、sdmmagpie.dtbをコピーして名前を変更するだけだと安全に判断できました。
dtbo.imgについては、fileはあまり役に立ちません。
dtbo.img: data
しかし、ここでmkdtimgまたはmkdtboimg.pyを使って解析できます。mkdtimg dump dtbo.imgを実行すると、次のようになります。

したがって、自分で作成するときは、次のいずれかを渡せばよいことがわかります。
mkdtimg create dtbo.img --page_size=4096 ../arch/arm64/boot/dts/qcom/sdmmagpie-idp-overlay.dtbo
または
mkdtboimg create --page_size=4096 dtbo.img ../arch/arm64/boot/dts/qcom/sdmmagpie-idp-overlay.dtbo
どちらのコマンドも同一のファイルを生成します。後でmkdtimg dump dtbo.imgを実行して、もう一方のファイルと値を比較することもできます。イメージに複数の.dtboファイルを含める必要がある場合は、どちらかのコマンドの最後にそのパスを追加するだけです。
さて、作成したテストカーネルに戻りましょう。良い知らせは、問題なくフラッシュできたことです。悪い知らせは、あのような汚い/proc/versionを生成するMakefileを修正しなければならないことです。
しかし、それは後回しにできます。さあ、ついにここまで来ました。
いくつかサブモジュールを追加する時です。まず、これには、とても分かりやすい手順が付属しています。(編集:さらに、私のCANサブシステムのカーネルシンボルを追加するプルリクエストがマージされたため、これにもCANサブシステムのカーネルシンボルが含まれています。ただし、以下のスクリーンショットには表示されません)。

そして、もう一度make nconfigを実行すると(以前と同じコマンド)、

この素晴らしい新しいオプションが表示されます。

これを選択すると、これらのすべてが有効になります。それを選択し、.configとして保存します。ただし、注意してください。out/.configに保存されるため、次にビルドする前にそのディレクトリ全体を削除することになります。ですから、nconfigを終了したら、そのファイルをカーネルソースディレクトリにコピーしてください。
次に、いくつかのソースファイルにパッチを当てる時です。nethunterビルドスクリプトのリポジトリをサブモジュールとして追加しましょう。

新しいディレクトリにcdして./build.shを実行し、オプション4: Apply Nethunter kernel patchesを選択します。

「テスト実行がエラーで完了しました」というメッセージが表示された場合は、パッチを適用しないでください。それ以外の場合は、適用して構いません。私の場合は、パッチ4、5、8を適用しました。
変更を加えたので、カーネルソースのトップディレクトリに戻ってコミットしましょう。

この時点で、単にカーネルを再ビルドすれば完了です。 しかし、私は凝り性なので、さまざまな追加機能のサポートを含めたいと思います。具体的には次のとおりです。

設定でこれらの新しく追加したドライバーを認識させるために、drivers/net/wireless/realtek内のKconfigとMakefileを変更する必要があります。さらに:

rtl8812au/Makefile内のプラットフォームをANDROID_ARM64に切り替えてください(rtl8188eusも同様です)。
また、新しく追加したドライバーのKconfigで、設定オプションが何という名前かを再確認する価値があります。

これで、一つ上のレベルのMakefileで88XXAUとして参照する必要があることがわかりました。

幸い、Kconfigは次のようにsourceされるだけです。

rtl88x2buとrtl8188fuのARMブランチを追加した後、これらのファイルをもう一度編集する必要があります。(そして、実際rtl88x2buの設定オプションはRTL8822BUという名前なので、常に確認する価値があるのです)。
次はMediaTekのバックポートドライバーです。このコミットをガイドとして、私は4.14.xカーネルを使用している2つの異なるデバイスにこれらのドライバーを移植することに成功しました。(コミット履歴がなぜ重要か分かりますか?) しかし、まずすべてのファイルを含むmt76ディレクトリが必要です。
4.19カーネルをgit cloneしてそこからファイルをコピーし、その新しいコピーのファイルに必要なパッチを当てる代わりに、https://github.com/akabul0us/mt76.gitをサブモジュールとして追加するだけで済みます。次に、drivers/net/wireless/mediatekディレクトリ内のMakefileとKconfigを編集します。

前述のコミットのパッチがソースにすでに適用されたこのリポジトリを追加することで、他のカーネルファイルに行う必要のある変更に進むことができます。最初の変更はこれです。

しかし、私たちのカーネルソースにはすでにこの構造体があることが判明しました。

そこで、次に変更するファイルinclude/linux/overflow.hに移ります。これには変更点がありますが、元のコミットで明確に読めるので、これ以上のスクリーンショットは省きます。include/linux/skbuff.hとinclude/linux/scatterplot.hにも変更がありますが、include/net/cfg80211.hには必要なものはありません。include/net/mac80211.hに必要な変更はわずかで、enum mac80211_rx_encoding { }内の最後の行にRX_ENC_HEを挿入し、struct ieee80211_rx_status { }にu8 vht_flag;を追加するだけです。net/wireless/of.cはすでに存在し、私たちがチェリーピックしているコミット内のものと同じなので、これで完了です。(ふぅ!)
Dockerサポートについては、これも(もう一度)cyberknight777のこれのおかげで、コピー&ペーストするだけで済みます。

これで、もう一度nconfigを実行する準備ができました! …ほとんど。まず、変更をコミットしてプッシュし、rm -rf out/を実行してから(.configをその外に保存したことを確認してください)、mkdir -p outを実行します。そして、その後に設定に戻れます。

カーネルに追加したツリー外Realtek USBドライバーについての注意事項: それらはちょっとひどいです。それらの複数をインラインでビルドしようとすると、リンク時にエラーが発生します。長年の解決策は、1つだけインラインでビルドし、残りはモジュールとしてビルドすることです。ただし、Mediatekドライバーは問題なくインラインでビルドできます。
結局、他にもたくさんのものを有効にしました。完全なdiffを見たい場合は、ここに置いてあります。とにかく、ビルドしましょう!

良いスタートです。追加したばかりの新しいオブジェクトファイルがエラーや警告なしにコンパイルされているのを目にすると、いつも気分がいいものです。

これは? あまり気分は良くないですが、修正は簡単です。警告フラグとしてそれを持っているMakefileから-Wno-stringop-overreadを削除するだけです。ついでに、-Werrorはちょっとハードコアすぎませんか?(このフラグは「すべての警告をエラーとして扱う」という意味で、未知の-Wフラグを含む、あらゆる問題でコンパイルを停止します)。

少なくともこれは簡単に修正できます。

その行の先頭に#を付けるだけで、makeを再び実行する準備ができます。そして今回は、最後まで完了しました!
しかし、いくつかのドライバーをモジュールとして設定したので、まだ完全には終わっていません。make modulesを実行する必要があります。より具体的には、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です。そして、ああもう、rtl8188fuのRealtekドライバーコードはめちゃくちゃです。

これらの警告を引き起こしている各行を手動で修正できますか? もちろん。しかし、やるでしょうか? いいえ。これらのドライバーをインラインではなくモジュールとしてコンパイルし、Realtekベースのアダプターを避けるよう皆に積極的に勧めているのには理由があります。しかしながら:

少なくとも、コンパイルは成功しました。それらにはすぐ戻ります。まず、カーネルzipを更新しましょう。

(もう忘れかけていましたが、これはもう「テスト」カーネルではなく、正規のNethunterカーネルです)。
モジュールについては、.tarファイルが本当におすすめです。含まれるファイルに関するすべてを保持できるからです。ただし、パスも保持されます。何か対策をしない限り、モジュールのtarballを展開すると、例えばdrivers/net/wireless/realtek/rtl8188fu/rtl8188fu.koのような、多数のディレクトリが作成されます。そこで、ディレクトリを作成し(.gitignoreに追加)、そこにコピーしてからアーカイブを作成しましょう。

これらをカーネルと同じようにフラッシュできますか?

これらはデバイス上のどこかに展開する必要があります。「どこか」と言うのは、insmod /whatever/path/to/whatever.koを実行したときにモジュールが読み込まれる限り、場所は本当にどこでもいいからです。/sdcardでも構いません。しかし、覚えておいてください、私は凝り性なので、このデバイスでは「適切な」場所、つまり/vendor/lib/modulesに展開します。もちろん、/vendorは読み取り専用でマウントされているため、そのパーティションに何かを行う前に、まずrootシェルを起動して(Nethunterターミナル内ではなく、それはchrootです。ただし、Nethunterターミナルアプリで「新しいセッション→ルートシェル」を選択すれば使えます)、mount -o rw,remount /vendorを実行する必要があります。その後、cd /vendor/lib/modules; tar xzvf /sdcard/or/wherever/you/saved/the/tarball.tgz; mount -o ro,remount /vendorを実行すれば、モジュールの作業は完了です。
そのパーティションに空き容量がないというエラーが発生した場合は、シンボリックリンクを使うこともできます。たとえば、/sdcard/modulesにファイルを置き、絶対パスを使ってリンクを作成します。88x2bu.koでこれを行う場合、ln -s /storage/emulated/0/modules/88x2bu.ko /vendor/lib/modules/88x2bu.koを実行します。

リポジトリに最後のプッシュを実行し、よければ、使用した.configをnethunter用の新しいdefconfigとして保存してください。(これはソースからビルドする人々にとって本当に助けになります)。
動作するのでしょうか? フラッシュは問題なくできます。しかし、実際に動作するのでしょうか?
もうかなり遅い時間なので、今すぐすべての機能をテストするつもりはありません。しかし、最も重要なもの、つまりカーネルに追加したドライバーでのモニターモード/パケットインジェクションを試してみましょう。まずはrtl88x2buから:

Realtekドライバーにしては、なかなかやりますね。
そして、メインイベント、mt76x2uです:

これこそペンテストデバイスです!
最後のステップは、.zipと.tar.gzをリリースとしてgithubにアップロードすることです。その後、xdaforums、Telegram、Twitterなど、同じデバイス/ROMのユーザーが見つけて恩恵を受けると思われる場所ならどこでも、それについて投稿しましょう。
そして、風呂に入っていない肛門を持つ恩知らずなバカが「お前、BUTTPHONE 34AC PRO EDITION用のカーネル作れよ?!!」と投稿に返信してきたら、このガイドへのリンクを渡して、上達しろと言ってやりましょう。
おやすみなさい、皆さん。
--Akabul0us