Communitygithub.com

angelwzr/linux-phone-porting

メインラインLinuxを[Android?]スマートフォンに移植するためのコーディングエージェントスキル

linux-phone-porting とは?

このスキルは、メインラインLinuxをAndroidスマートフォンに移植するための体系的な手順を提供します。デバッグサイクルはビルド、フラッシュ、ブートの各ステップを含み、通常5〜10分かかるため、盲目的な修正は失敗しやすいことを前提としています。スキルは、移植プロセスを0〜2のフェーズに分割し、厳密な順序で実行することを要求します。フェーズ0では、デバイスの正確な識別、ターゲットディストリビューション、ブートトポロジー、リカバリ状態の確立と、ユーザーデータを除く全パーティションのバックアップを実施します。フェーズ1では、ライブデバイスからの証拠収集(dmesg、pstore、ramoops、USB ACMコンソール)の方法と、測定値を解釈するための5つのルールを提供します。フェーズ2では、実装前の調査として、メインラインカーネル、ベンダーカーネルソース、postmarketOS、Halium/UBports、Mobian、NixOSの6つのソースファミリーを網羅的に調査することを推奨しています。このスキルは、Claude Code、Cursor、CodexなどのAIエージェントプラットフォームで使用するように設計されています。

対応~Claude Code~Codex CLI~Cursor
npx skills add angelwzr/linux-phone-porting

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Linux Phone Porting

メインラインLinuxを起動中のスマートフォンでは、デバッグイテレーションにビルド、フラッシュ、ブート(5〜10分)がかかり、盲目的な修正は成功よりも却下されることの方がはるかに多いです。以下の順序に厳密に従ってください。

0. ポートのセットアップ

これは、最初のフラッシュの前に一度だけ行います。これをフェーズ0ではなく単なる書類手続きとしない理由は2つあります:ストックシステムはこのボードに関してこれまでで最も信頼性の高い調査ソースであり、パーティションを上書きし始めるとその一部が読み取れなくなるからです。

まずターゲットを確定します。その後のすべての回答はこれに依存します。

  • 正確なデバイス識別 — マーケティング名、コードネーム、SoC、および地域またはストレージのバリエーション。同じマーケティング名の兄弟バリエーションは、パネル、タッチコントローラー、またはモデムが異なることがよくあり、間違ったバリエーションに対して調査された修正はもっともらしく見えて失敗します。
  • ターゲットディストリビューションとinit — postmarketOS、Mobian、NixOS、通常のDebian、その他。これにより、パッケージング、イメージレイアウト、およびフェーズ2のどのソースが最も近いかが決まります。
  • ブートトポロジー — A/Bまたは非A/B、スロットレイアウト、およびブートローダーのロック状態。ロック解除されたブートローダーのみ。 ブートローダーがロックされている場合は、停止してください:このスキルはブートローダーのロックを解除せず、その手順も提供しません — ユーザーをOEMの指示に誘導し、デバイスのロックが解除されたら再開してください。
  • リカバリ — カスタムリカバリがインストールされているかどうか。必須ではありません:バックアップと復元のための便利な機能です。

次に、userdataを除くすべてのパーティションの完全バックアップを取ります:

  • userdataをスキップ:それはスペースの大部分であり、ユーザーのデータであり、失っても問題ない唯一のパーティションです。
  • デバイス固有のパーティションをバックアップし、決して公開しないでください。 モデムNV/EFS、persist、およびそれらのキャリブレーション関連パーティションには、IMEI、無線キャリブレーション、およびこの個々の端末のセンサートリムが含まれています。これらはインターネット上のどのイメージからも再現不可能であり、これらを破損するポートはネットワークに登録できない電話を残します。これらを重要かつプライベートとして扱ってください。
  • すべてのイメージをハッシュ化し、パーティションテーブルと一緒にハッシュを記録します。後で「デバイス上にあるものはまだバックアップしたものか」という質問に答える必要があり、ハッシュだけがそれに答えます。
  • バックアップが実際に復元可能であることを、最初のリスクのあるフラッシュの前に確認し、後ではなく確認します。

バックアップがリカバリ以上の調査としての価値:

  • ストックDTB — このボードのデバイスツリーの根拠であり、兄弟SoCのdtsiがそれと矛盾する場合の決定打となります。
  • ファームウェアblobとそのロード順序 — ベンダースタックが実際に提供するものと、それがどこにあることを期待するか。
  • ベンダーカーネルのcmdlineとブートイメージレイアウト — オフセット、ヘッダーバージョン、およびストックカーネルに与えられた引数。
  • 正確なカーネルバージョン文字列 — ストックROMからの uname -a または /proc/version(まだ読み取れるうちに、後でバックアップしたブートイメージからも展開可能)。これは、フェーズ2で適切なGPL公開OEMソースリリースを選択する指紋です。ベンダーはいくつかのビルドを出荷し、それらは異なります。
  • ベンダー設定 — メインラインドライバーが満たさなければならないインターフェースを説明するセンサー、モデム、およびHAL設定。

最後に、セッションの残りが想定する作業規則を設定します:ログとpstore用にブートごとに1つのサブディレクトリを蓄積するホスト側ディレクトリ、および動作することがわかっているリカバリパスのメモ。以前の試行からのバックアップがすでに存在する場合は、それがこれらのパーティションをカバーしていること、およびそのハッシュがまだ検証されていることを確認し、そうであると仮定しないでください。

1. 最初にライブデバイスから証拠を収集する

何かを変更する前に、失敗した実行の完全なdmesgをキャプチャします。再現する前に関連するデバッグノブを有効にします(例:echo 0xffffffff > /sys/module/<driver>/parameters/debug_mask)。2回目の再現には別のブートが必要になるためです。

証拠のチャネル(信頼性のおおよその順序):

  • ネットワークまたはUSB経由のライブシェル。 最も安価なチャネル。デバイスが稼働している間はこれを使用します。
  • pstore。 systemdが起動したら、/var/lib/systemd/pstore/ から収集します。/sys/fs/pstore/ からは収集しないでください — systemd-pstore.service はすべてのレコードをブートの早い段階で移動するため、空の /sys/fs/pstore はクラッシュが記録されなかったという証拠にはなりません。コンソール領域は通常1つのスロットです:他のことをする前にそれをホストにコピーしてください。そうしないと、次のクラッシュによってアーカイブでも上書きされます。
  • ramoops。 損失があるものとして扱います。DRAM電荷保持は電源オフの期間にわたって減衰します — あるデバイスでは約6.5%のビットが測定され、ゾーンヘッダーでECCを失敗させ、レコードを完全に失うのに十分です。レコードをあいまいにgrepします。領域を劣化させるのは、電源を切る前にスパムを送信するのに費やした時間ではなく、電源がオフのまま費やされた時間です。そのため、スタックしたデバイスをコンソールゾーンが保持できる限りログを記録させ、その後すぐに電源を切って再びオンにします。ゾーンサイズを確認してから、急ぐ必要があると想定しないでください:4 MiBのコンソールゾーンは、ラップする前に何時間ものウォッチドッグスパムを吸収します。
  • カーネルレベルのUSB ACMコンソール(CONFIG_U_SERIAL_CONSOLE=y と cmdlineの console=ttyGS0)。スタック状態でも生き残る唯一のチャネルであり、ポートの早い段階での1回のフラッシュコストに見合う価値があります。ユーザースペース ACM gettyはスタック状態では生き残りません — スケジュール可能なCPUが必要であり、USB経由で問題なく列挙している間は0バイトを生成します。両方の半分が必要です:設定シンボルだけではファシリティは不活性のままです。

推測を測定に繰り返し変える5つのルール:

  • 実際にフラッシュされているものを、パーティションを読み戻して確認します。メモからでもビルドログからでもありません。iflag=direct で読み取り、読み取り自体がデバッグ中のものを妨害しないようにします。サイズのみの比較に注意してください — ブートイメージは固定サイズにパディングされているため、2つの異なるイメージで同じ長さであっても何も証明されません。ペイロードをハッシュ化します。
  • デバッグインターフェースを読み取ると症状が生じることがあります。 DRM/GPUクラッシュ状態ノードは古典的なケースです:GPUがアクティブに送信中にサンプリングすると、実際には発生しなかった障害とリカバリのラインが合成されます(測定値:5回の読み取り、5つの障害/リカバリペア、観測されなかった場合と比較)。ログラインを信頼する前に、自分の観測がそれを生成したかどうかを確認してください。
  • マッピングされたerrnoを解釈する前に、拒否の生の応答をキャプチャします。 ファームウェアコールのマッピングされたエラーは曖昧でした — EINVAL は不正なエンコーディングか拒否されたポリシーのいずれかを意味する可能性がありました — コールラッパー内の動的デバッグが生の応答ワードを公開するまで:明確な拒否を伴う適切に形成されたコール。それはポリシーであり、エンコーディングではありません — 反対の評決であり、反対の次のステップがあります。すべてのファームウェア拒否を、それに基づいて行動する前に、不正なエンコーディング、ポリシーによって拒否、見つからないのいずれかに分類します。鏡のルール:クリーンで適切に形成された否定は肯定的な証明です — 正しく形成されたルックアップからの「見つからない」はエンコーディングを検証し、ローダーに触れることなく計画のブランチを排除します。
  • 制御されていない状態と競合する測定は、もっともらしい無効な数値を返します。 あるベンチマークは2秒で55を記録しました:コンポジタがDRMマスターを保持し、すべてのシーンが失敗し、条件がチェックされるまで数値は実際のように見えました。有効な比較 — 132 → 485 — は、両方の実行でコンポジタを停止し、その世代内でのみ比較する必要がありました。ベンチマークを信頼する前に、それを無効にする可能性のある条件に名前を付け、それがすべての実行で保持されたことを確認します。
  • 撤回したルールを記録します。 ブートアップは民間伝承を急速に蓄積し、あるハードウェアリビジョンまたはバッファサイズに対して正しかったルールは、変更された後は積極的に誤解を招くものになります。変更された内容とともに、現在のルールの隣に覆されたバージョンを保持しておくと、次のセッションでどのアドバイスがストレステスト済みかを知ることができます。

事前に防ぐ価値があるホスト側の落とし穴:

  • timeout N ssh <device> '<cmd>' はローカルクライアントのみを強制終了します。リモートプロセスは実行を継続します。明示的なkillでフォローアップします。
  • pgrep -f および pkill -f は、同じsshパスを介して実行すると、独自のリモートシェルを自己マッチします。マッチャーをフィルターで除外するか、PIDで一致させます。
  • 開始パスがシンボリックリンクの場合、find には -L が必要です。そうしないと、黙って空の結果を返します。
  • コマンド出力を書き換えるラッパーまたはフック — トークンフィルター、ページャー、フォーマッター — は証拠を破損し、時には明らかに壊れるのではなくテストを逆転させます。発見としてコミットするものには生のコマンドを使用します。

2. 実装前に調査 — これらすべてのソース

調査は常に実装に先行します。何を消費するかは、何をしているかによって異なります:

  • 失敗の調査 — フェーズ1の証拠。最初にキャプチャします。実際に読んでいない症状を調査することは、引用付きの推測です。
  • 機能の追加 — これまで登場したことのないドライバー、ペリフェラル、サブシステム — フェーズ0のアーティファクトがデバイスデータです。ストックDTB、ベンダー設定、およびファームウェアレイアウトは、このボードがそのものを駆動することを期待する方法を説明し、クラッシュログと同じくらいここで信頼性があります。

いずれにせよ、何かを書く前に:

  1. サブシステムについて推論する — どのドライバー、バインディング、またはファームウェアインターフェースが失敗を所有しているか、または新しい機能を所有するかを特定します。利用可能なスキルはセッションコンテキストにリストされています:今そのリストをスキャンし、カーネル開発またはクラッシュ分析スキルがある場合は、続行する前にそれを読んでください — そのレジスタレベルおよびバインディングの詳細は、このステップに正確に必要なものです。スキルがリストされていない場合にのみ、直接推論します。
  2. 関連するユーザースペースライブラリとツールを調べる — 記憶からではなく、現在のドキュメント。同じセッションリストにドキュメント検索スキルがある場合は、記憶から署名を呼び出すのではなく、それを実行します。
  3. 6つのソースファミリーすべてにわたるウェブ調査(並列サブエージェントがここではうまく機能します。ウェブ調査スキルがそのリストにある場合は、キャッシングのためにそれを優先します。セッションは同じページを再読み取りするため):
    • メインライン — lore.kernel.org、ドライバーソース、DTバインディング、および最も近い兄弟SoC(同じファミリー、または同じRPM世代)のdtsi。「ダウンストリームドライバーを移植する」キャンペーンの範囲を決める前に、メインラインがすでにそのインターフェースに対して持っているものを掃引します:そのエクスポートされたAPI、ユーザースペースに到達するかカーネル内部のみか、およびそのゲート — マシン許可リスト、「ブートローダーによってプリロードされた」セマンティクス、モジュールではなく組み込み(測定値:そのような掃引の1つで、9.4k行のダウンストリームポートが約300行のプローブモジュールに削減されました。メインラインがすでに許可リストの背後でカーネル内部的にインターフェースを運んでいたためです — 計画は既存のAPIを駆動することになり、それを移植することではありませんでした)。
    • ダウンストリームベンダーカーネル — GPL公開OEMソース。 GPLv2はAndroid OEMに出荷したカーネルソースを公開することを義務付けているため、このデバイスの正確なリリースが通常存在します:OEMのオープンソースポータル(Samsung、Sony、Xiaomi、Fairphone、OnePlus/OPPO、Motorolaはすべて運営しています)、そのGitHub/GitLabミラー、およびポータルリンクが死んだ場合のXDAなどのコミュニティアーカイブ。バージョン文字列がフェーズ0の /proc/version と一致するtarballを選択します — ベンダーはいくつかのものを公開し、それらは異なります。コンプライアンスの品質はさまざまであるため、ツリーをマイニングするためのオラクルとして扱います — この正確なデバイスのボードdtsとdefconfig、およびツリー外のベンダードライバー(タッチ、パネル、充電器、モデムグルー)とそのレジスタシーケンスおよびファームウェアハンドシェイク — 構築できると想定するのではなく。正確なリリースが見つからない場合でも、兄弟デバイスのリリースは通常、SoC dtsiを運んでいます。さらに良い:デバイス自体から取り出したストックDTB(dd で untouched ブートスロット、d00dfeed をスキャン、dtc -I dtb -O dts)。これは_この_ボードの根拠であり、兄弟SoCの推測を何度も修正してきました — 兄弟SoCが間違え、ストックDTBが正しかったSMMUストリームIDなど。
    • postmarketOS — pmaportsデバイスパッケージとAPKBUILD、マージリクエスト、wikiデバイスページ、およびSoC-mainlineツリー。
    • Halium / UBports — halium/android_device_* ツリー、hybris-boot 設定、およびUBportsデバイスポート。HaliumはメインラインではなくAndroidベンダースタックを実行するため、_ベンダーファームウェア_がどのように駆動されることを期待するかについての最良のソースです:ファームウェアblobのパスとロード順序、デーモンが期待するプロパティおよびソケットインターフェース、センサーおよびモデムHAL設定。メインラインドライバーがプローブするがファームウェアハンドシェイクが失敗する場合 — または、まだサポートされていないペリフェラルがどのハンドシェイクを期待するかを知る必要がある場合 — これが通常、欠けているピースが書き留められている場所です。
    • Mobian — Debianデバイスリポジトリ。
    • NixOS — mobile-nixosパターンとnixpkgsパッケージング。

薄い結果は通常のケースであり、ブロッカーではありません。 ポートに必要なもののほとんどは、このボードでは決して行われておらず、多くの場合、このSoCでも行われていません。6つのソースが何も報告しないことは、誰もその作業を公開していないことを意味します — 作業を停止したり、戻したりする必要があることを決して意味しません。先例がない場合でも、答えはまだ主要なアーティファクトにあります:すでにペリフェラルを駆動しているツリー外のベンダードライバー(レジスタシーケンス、ファームウェアハンドシェイク、GPIOおよびレギュレータ配線)、それ用のストックDTBの独自ノード、ユーザースペースが期待するものを命名するベンダーHAL設定、および構造テンプレートとして同じデバイスクラスの最も近いメインラインドライバー。それらを読み、設計を導き出し、欠けているピースを作成します — DTノード、クirk、小さなドライバー。そのピースを作成することは、ブートアップの通常の終端状態であり、正当化されるべき例外ではありません。フェーズ0のバックアップと1変数-フラッシュルールは、間違った導出が他の反論と同じ1回のブートと1つの元帳行になるように正確に存在します。

空のスイープと空のスキャンは異なる結果です。 ソースの空のスイープは、誰もその作業を公開していないことを意味します。空の_スキャン_ — 何も返さない抽出 — は、同じメソッドが既知の陽性に対して実行され、そのカバレッジが検証されるまで無効です:ファイル数、セグメントリスト、globが実際に一致したもの。測定されたニアミス:globは27のファームウェアセグメントのうち9つに一致し、誤った「ファームウェアがそれを省略している」をほぼ記録しました。ライブラリスキャンは、既知のチップIDを陽性対照として見つけた後でのみ信頼できるようになりました。

ダウンストリーム識別子はダウンストリームの問題であり、メインラインの問題ではありません。 ベンダードライバーは、...

[...以下に続く...]

関連スキル