デバイスツリー
18 の .dtsi と 1 つの .dts
端末自身の vendor_boot から取り出した出荷時 DTB — ソースではなくコンパイル済みバイナリ — を逆コンパイルし、クロック、pinctrl、レギュレータ、ディスプレイ、カメラ、音声、サーマル、予約メモリまでを読める .dts / .dtsi に組み直しました。dtc の警告はゼロ。2 本のカーネルで共有しています。
独立したデバイスサポート · MediaTek MT6789 / MT8781
復元したデバイスツリーと 2 本のカーネル、そしてその上のユーザー空間。本来ベンダーが担うサポート一式を、外側から作って公開しました。
この端末が毎日動いているのは Linux 6.12 です。その手前の 6.1 の移植も、アーカイブとして隣に残しています。あわせてカーネル外のドライバツリーが 339、うち 290 モジュールが起動時に読み込まれ、デバイスツリーはコンパイル済みバイナリから読める形に復元しました。カーネルより上のクローズドな部分も一つずつオープンに書き直しています — 今のところ音声 HAL、センサー HAL、HIDL→AIDL ブリッジ 4 本。動いていても読めないバイナリは調整できず、作られた時点の Android から動けないからです。
進行中 · 最終更新
この仕事が実際に何だったか
ソースが公開されていない端末は、ロックされた端末ではありません。ドライバを書かないかぎり、そもそもドライバが存在しない端末です。
ベンダーのカーネルソースも、デバイスツリーも、リファレンス BSP も、問い合わせ先すら、手に入るものは何一つありませんでした。土台は Google の Android Common Kernel、カーネル外のドライバは MediaTek がチップ向けに公開を義務づけられている GPL ソースから始めて、基板に合わせて一つずつ直しています。これが設定作業ではなくサポート一式である理由は、書かなければならなかった量にあります — 339 のドライバツリーのうち 172 に自前の修正が入り、10 個のモジュールはここにしか存在せず、デバイスツリーは他に読むものがないのでバイナリから解いてきました。
設定ではなく、書いたもの
代わりにあったのがバイナリだったので存在する 7 つ。出発点となるソースがそもそもなかったか、動いてはいるが手を入れられないベンダーのブロブがあったかのどちらかです。
18 の .dtsi と 1 つの .dts
端末自身の vendor_boot から取り出した出荷時 DTB — ソースではなくコンパイル済みバイナリ — を逆コンパイルし、クロック、pinctrl、レギュレータ、ディスプレイ、カメラ、音声、サーマル、予約メモリまでを読める .dts / .dtsi に組み直しました。dtc の警告はゼロ。2 本のカーネルで共有しています。
1,800 行
MediaTek AFE 向けの完全なプライマリ HAL で、ベンダーのバイナリを包むのではなく置き換えるために書きました — そもそも音声経路に手が届くようになったのはそのおかげです。スピーカーのハイパスと共有リミッタはバイナリのままでは不可能な調整ですし、マイクはコーデックのデジタルマイク経路を有効にし、アナログ種別は触らない必要がありました。出荷時のミキサー設定では無音を録音して、エラーも出しません。
2,400 行
ベンダー実装に代わるオープンな実装で、カーネルの hf_manager インターフェースに直結し、較正値は工場出荷時の nvcfg パーティションから読みます。2 本のワーカースレッドはいずれも実イベントで待つので、全センサーを切れば HAL はウェイクアップを一切起こしません — コードが自分のものになって初めて直せる類の話です。
2,100 行
指紋、gatekeeper、セキュアエレメント、テザリングオフロードの 4 つのサービスが、まだ書き直していないクローズドな HIDL HAL へ AIDL を橋渡しします。起動時に一度バインドして終わりではなく、相手が落ちても生き延びます。Android 16 の要件ではなく Android 17 への地ならし — ベンダーバイナリが想定していない VINTF レベルへ端末を動かせるのは、この継ぎ目があるからです。
ベンダーに相当物なし
出荷時のテーブルが記述していなかったサーマルゾーン、復帰後に PMIC の割り込み有効化を張り直すガード、この基板固有のストレージと RF レギュレータの挙動、そして何度も役に立ったのでツリーに残した立ち上げ用の計測コード。
挙動から再構築
MediaTek の USB コントローラドライバを組み直したものです。端末がまったくサスペンドできなくなる不具合を直します — ケーブルを抜くとガジェットの後片付けが切断処理より先に走り、ドライバ自身の解放経路に到達できないまま wakeup source が握られっぱなしになっていました。
10,000 行・未同梱
オープンな CCCI スタック — 起動時にモデムが必要とするファイルサービス、起動と状態管理のデーモン、RPC デーモン、ライン規律の多重化、そして最小限の RIL。ROM には意図的に入れていません。RIL は 201 メソッド中 27 しか実装しておらず、緊急発信はまだスタブです。人が持ち歩く電話に載せるものではありません。
その上で端末は何ができるか
| State | サブシステム | 備考 |
|---|---|---|
| 動作 | ディスプレイ | パネル、バックライト、スリープと復帰。カタログは 90 Hz ですが、実際にパネルを駆動しているのは 96 Hz です。コンポジタのフレーム予算を本当の周期 10.4 ms に合わせ直したところ、90 パーセンタイルのフレームが 150 ms から 25 ms になりました。 |
| 動作 | 音声 | スピーカー、受話口、マイク、Bluetooth A2DP、通話音声 — すべてここで書いた HAL を通ります。スピーカーには 180 Hz のハイパスとチャンネル共有のリミッタを入れ、ピークでステレオ像がずれないようにしています。 |
| 動作 | 携帯通信 | 通話、SMS、モバイルデータを実回線で確認。モデムスタックは出荷時のものです。並行して作ったオープンなスタックは ROM には入れていません。 |
| 動作 | 無線 | Wi-Fi、Bluetooth、NFC。Wi-Fi はカーネルモジュールの内側から立ち上げ、規制上のカントリーコードもそこで設定します。設定しないと接続まで至りません。 |
| 動作 | カメラ | 反転モジュールの論理カメラ 2 つとも — 静止画と動画。 |
| 動作 | 指紋 | 登録と照合。照合そのものはクローズドな trustlet の中で動いていて、これは今後も変わりません。 |
| 動作 | USB | adb と MTP。以前はガジェットが認識されて 2 秒で消えていました。完全な出荷時イメージでも再現したので、この不具合は今回の作業で入ったものではなく工場出荷時からあったと確認できました。 |
| 動作 | 電源 | 工場出荷のバイナリから復元したドライバによる充電、CPU の両クラスタと GPU のサーマルゾーン、ケーブルを抜いた状態でのサスペンドと復帰。 |
| 未完成 | RPMB | ハードウェア鍵ストレージが MAC 検証に失敗します。ストレージは安全に縮退し、起動には影響しません。起動経路が工場で書き込まれた鍵とは別の鍵を導出している可能性が高く、そうであれば工場の鍵素材なしには直せません。 |
| 未対応 | もう一方のスロット | A/B 両スロットの論理パーティション 6 つがすべて super 内の同じオフセットから始まるため、この端末に「空いているスロットに焼いて試す」は存在しません。ハードウェアの欠陥ではなく、インストールのやり方から来る結果で、先にそのスロットのメタデータを書き直せば解決します。 |
| 未対応 | 仮想 SIM | この端末の売りである内蔵 vSIM。意図的に手をつけていません。 |
動作 未完成 未対応
どの行も実機で実際に使ったという意味で、ドライバがバインドしたとかデバイスノードが現れたという意味ではありません。かつてまさにその根拠で「動作」と記録したサブシステムが 3 つあり、3 つとも動いていませんでした。
動かしている端末
MindOne は MediaTek Helio G99 を積んだ市販の端末です。カードサイズ、サファイアの下に正方形の AMOLED、5000 万画素のレンズ 1 枚が反転して前面カメラにも背面カメラにもなります。ここに諸元を載せているのは、作業がこの条件に合わせる必要があったからで、端末を勧めるためのページではありません。出荷時は Android 12 世代のベンダーイメージ上の Linux 5.10 で、ブートローダーより上はすべて、下に挙げた 2 つのリポジトリで置き換わっています。
数字で見る
検証したこと、していないこと
一人による独立した立ち上げです。粗いところがあるものと考え、おかしな挙動はたいてい既知だと思って構いません。工場出荷ファームウェアに戻す手段は必ず確保してください。
どう公開しているか
どちらのリポジトリもベンダーのバイナリを使わずソースからビルドでき、クリーンなクローンが生む ABI は端末で動いているものと同じです。カーネルのリポジトリは Android Common Kernel 自身と同じく、カーネルのバージョンごとにブランチを持ちます。android16-6.12 をビルドし、デバイスツリーをそれに対してビルドしてください。
Linux 6.12.92 · 現行
Google の Android Common Kernel、ブランチ android16-6.12-lts を手作業で移植し、デバイスサポートを載せたものです。復元したデバイスツリー、752 項目の defconfig、カーネル外のドライバツリー 339 本、そのうち 290 モジュールが実機で読み込まれます。出荷時のカーネルから 2 世代先で、現在の作業はすべてこのブランチに入ります。同じツリーと同じツールチェーンでの 2 回のビルドはバイト単位で同一の Image を出すので、端末で動いているものとクリーンなクローンから得られるものは同一物です。
Linux 6.1.175 · アーカイブ
元のベンダーカーネルからの最初の移植で、6.12 を可能にした一段です。デバイスツリーとドライバ作業の大半が実機で最初に確かめられたのはここでした。6.12 に置き換わるまでは日常用のカーネルとして動いていました。履歴として残していますが保守はしていません — 修正も、セキュリティのバックポートも、テストもありません。ドライバはここには重複して置かれておらず、6.12 ブランチにあって互換ヘッダ 1 枚でどちらのカーネルにも通ります。
LineageOS 23.2 · Android 16 · 現行
LineageOS のデバイスツリーは普通は設定を運ぶものですが、ここには約 16,400 行の実装が入っています。クローズドなユーザー空間を、そのまま包み直すのではなく書き直しているからです。完全なプライマリ音声 HAL、カーネルの hf_manager に直結したセンサー HAL、VINTF のレベルが上がるなかでまだ書き直していないベンダー HAL を生かす HIDL→AIDL ブリッジ 4 本、そしてオープンなモデム用ユーザー空間。ここでビルドした super パーティション一式 — system、vendor、product、system_ext、両方の dlkm — がそのまま端末で起動します。
公開しないもの
この端末がなお必要とするプロプライエタリなユーザー空間 — 無線、GPU ドライバ、カメラライブラリ、そしてまだ書き直していない HAL — はどちらのリポジトリにもありませんし、今後も置きません。各自が自分の端末から取り出すものです。MediaTek と iKKO のバイナリも同様で、ブートローダー、セキュアファームウェア、コプロセッサのイメージ、モデムファームウェア、この個体のパーティションダンプは含みません。
使用技術
免責事項
このページに書かれていることは、明示・黙示を問わずいかなる保証もなく現状のまま提供されます。ブートローダーのアンロック、パーティションの書き換え、ここからリンクしているツールの実行は、端末上のすべてのデータを消し、端末を恒久的に起動不能にする可能性があります。実行はご自身の責任と判断で行ってください。ここに書かれたことに従った結果として生じた損失や損害について、端末に対するものかどうかを問わず、著者は一切の責任を負いません。
小売で購入した端末での個人的な研究プロジェクトであり、1 台の個体で起きたことの記録です。iKKO および MediaTek とは無関係で、両社の承認も支援も受けていません。