Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る
このページは Cloud Translation API によって翻訳されました。
Switch to English

一般的なカーネルイメージ

Android Common Kernel(ACK)は、すべてのAndroid製品カーネルの基盤です。ベンダーとデバイスのカーネルはACKの下流にあります。ベンダーは、カーネルソースコードを変更し、デバイスドライバーを追加することで、SoCおよび周辺機器のサポートを追加します。これらの変更は広範囲に及ぶ可能性があり、デバイスで実行されているコードの50%がツリー外のコードです(アップストリームLinuxまたはAOSP共通カーネルからではありません)。

したがって、デバイスカーネルは次のもので構成されます。

  • アップストリーム:kernel.orgのLinuxカーネル
  • AOSP:AOSP共通カーネルからの追加のAndroid固有のパッチ
  • ベンダー:ベンダーからのSoCおよび周辺機器の有効化と最適化のパッチ
  • OEM /デバイス:追加のデバイスドライバーとカスタマイズ

ほぼすべてのデバイスにカスタムカーネルがあります。これはカーネルの断片化です。

Androidカーネル階層は断片化につながります

1.Androidカーネル階層が断片化につながる

断片化のコスト

カーネルの断片化は、Androidコミュニティにいくつかの悪影響を及ぼします。

セキュリティの更新は労働集約的です

Android Security Bulletin(ASB)で引用されているセキュリティパッチは、各デバイスカーネルにバックポートする必要があります。ただし、カーネルの断片化により、セキュリティ修正を現場のAndroidデバイスに伝播するのは非常にコストがかかります。

長期的にサポートされているアップデートをマージするのが難しい

長期サポート(LTS)リリースには、セキュリティ修正およびその他の重大なバグ修正が含まれています。 LTSリリースを最新の状態に保つことが、セキュリティ修正を提供するための最も効果的な方法であることが証明されています。 Pixelデバイスでは、ASBで報告されたカーネルセキュリティの問題の90%が、最新の状態に保たれているデバイスですでに修正されていることが発見されました。

ただし、デバイスカーネルにすべてのカスタム変更があるため、LTS修正をデバイスカーネルにマージすることは困難です。

Androidプラットフォームのリリースアップグレードを禁止します

断片化により、カーネルの変更を必要とする新しいAndroid機能を現場のデバイスに追加することが困難になります。 Android Frameworkコードは、最大5つのカーネルバージョンがサポートされており、新しいプラットフォームリリースではカーネルの変更が行われていないことを前提としている必要があります(Android 10は3.18、4.4、4.9、4.14、および4.19カーネルをサポートしていますが、サポートされていない場合もあります) 2017年のAndroid8以降の新機能で強化されています)。

カーネルの変更をアップストリームLinuxに戻すのは難しい

カーネルにすべての変更が加えられているため、ほとんどのフラッグシップデバイスには、少なくとも18か月前のカーネルバージョンが付属しています。たとえば、4.14カーネルは2017年11月にkernel.orgによってリリースされ、4.14カーネルを使用した最初のAndroidフォンは2019年春に出荷されました。

アップストリームカーネルのリリースと製品の間のこの長い遅延により、Androidコミュニティが必要な機能とドライバーをアップストリームカーネルにフィードすることが困難になるため、断片化の問題を修正することは困難です。

断片化の修正:汎用カーネルイメージ

Generic Kernel Image (GKI)プロジェクトは、コアカーネルを統合し、SoCとボードのサポートをコアカーネルからロード可能なモジュールに移動することで、カーネルの断片化に対処します。 GKIカーネルは、カーネルモジュール用の安定したカーネルモジュールインターフェイス(KMI)を提供するため、モジュールとカーネルを個別に更新できます。

GKI:

  • ACKソースから構築されてます
  • あるシングルカーネルバイナリプラス(現在のみarm64 LTSリリースごとのアーキテクチャごとにロード可能なモジュールを、関連するandroid11-5.4android12-5.4 )。
  • 関連するACKのためにサポートされているすべてのAndroidプラットフォームのリリースでテストされています。 GKIカーネルバージョンの存続期間中、機能の廃止はありません
  • 特定のLTS内のドライバーに安定したKMIを公開します。
  • SoCまたはボード固有のコードは含まれていません

GKIが実装されたAndroidデバイスの外観は次のとおりです。

GKIアーキテクチャ

2.GKIアーキテクチャ

GKIは複雑な変更であり、Android11プラットフォームリリースのv5.4カーネルからいくつかの段階で展開されます。

GKI 1.0 —GKIの互換性要件

Android 11プラットフォームリリースで起動する一部のデバイスでは、Trebleの互換性のために、v5.4カーネルを実行しているデバイスのGKIテストが必要です。

GKI互換性テスト用のパーティション

3.GKI互換性テスト用のパーティション

GKIの互換性とは、デバイスがVTSおよびCTS-on-GSI + GKIテストに合格し、GKIブートイメージをbootパーティションにフラッシュし、GSIシステムイメージをsystemパーティションにフラッシュすることにより、 Generic System Image(GSI)およびGKIカーネルをインストールすることを意味します。デバイスは別の製品カーネルで出荷でき、GKIが提供していないロード可能なモジュールを使用できます。ただし、製品カーネルとGKIカーネルの両方が、同じvendor_bootおよびvendorパーティションからモジュールをロードする必要があります。したがって、すべての製品カーネルには、同じバイナリカーネルモジュールインターフェイス(KMI)が必要です。ベンダーは、GKI KMIとの互換性が維持されている限り、製品カーネルのKMIを拡張できます。ベンダーモジュールがGKI1.0でアンロード可能である必要はありません。

GKI1.0の目標

  • 製品カーネルがGKIカーネルに置き換えられたときに、VTSまたはCTSにリグレッションを導入しないでください。
  • OEMおよびベンダーがAOSP共通カーネルを最新の状態に保つためのカーネルメンテナンスの負担を軽減します。
  • デバイスが新しいAndroidプラットフォームリリースにアップグレードされているか、新しく起動されたかに関係なく、Androidのコア変更をカーネルに含めます。
  • Androidユーザースペースを壊さないでください。
  • ハードウェア固有のコンポーネントを、ロード可能なモジュールとしてコアカーネルから分離します。

GKI2.0-GKI製品

カーネルバージョンv5.10以降を使用してAndroidS (AOSP実験的) (2021)プラットフォームリリースで起動する一部のデバイスは、GKIカーネルとともに出荷する必要があります。署名されたブートイメージが利用可能になり、LTSと重大なバグ修正で定期的に更新されます。 KMIのバイナリ安定性が維持されるため、これらのブートイメージは、ベンダーイメージを変更せずにインストールできます。

GKI2.0の目標

  • GKIでパフォーマンスや電力の大幅な低下を引き起こさないでください。
  • OEMがベンダーの関与なしにカーネルセキュリティ修正とバグ修正(LTS)を提供できるようにします。
  • デバイスのメジャーカーネルバージョンを更新するコストを削減します(たとえば、v5.10から2021 LTSカーネルへ)。
  • アップグレードのための明確なプロセスでカーネルバージョンを更新することにより、アーキテクチャごとに1つのGKIカーネルバイナリのみを維持します。

GKIデザイン

KMIカーネルブランチ

GKIカーネルは、ACK KMIカーネルブランチから構築されます。これについては、 Android CommonKernelsで詳しく説明されています。 KMIは、カーネルバージョンとAndroidプラットフォームリリースによって一意に識別されるため、ブランチの名前は<androidRelease>-<kernel version>です。例えば、Androidの11のための5.4 KMIカーネルブランチの名前はandroid11-5.4. Android S(AOSP実験的) (コミットされておらず、新しい分岐モデルが将来どのように進行するかを示すためにのみ示されています)の場合、2つの追加のKMIカーネル、 android12-5.4と新しいLTSカーネルに基づく2番目のカーネルがあるとandroid12-5.4れます、2020年末に宣言する必要があります。

KMIカーネル階層

図4は、5.10KMIカーネルのブランチ階層を示しています。 android12-5.10アンドロイドS(AOSPの実験)に対応するKMIカーネルですandroid13-5.10アンドロイドT(AOSPの実験)(コミットのみ新しい分岐モデルは、将来的に進行する方法を示すために示されていない)に対応しています。

5.10のKMIカーネル階層

4.5.10のKMIカーネル階層

図4に示すように、KMIブランチは、開発(dev)、安定化(stab)、および凍結の3つのフェーズを循環します。これらのフェーズについては、 Android CommonKernelsで詳しく説明されています。

KMIカーネルがフリーズした後は、安定したKMIに影響を与えずに軽減できない重大なセキュリティ問題が特定されない限り、KMIを破る変更は受け入れられません。ブランチは、その存続期間中ずっと凍結されたままです。

バグ修正とパートナー機能は、既存のKMIが壊れていない限り、凍結されたブランチに受け入れることができます。 KMIは、現在のKMIを構成するインターフェイスが影響を受けない限り、新しくエクスポートされたシンボルで拡張できます。新しいインターフェイスがKMIに追加されると、すぐに安定し、将来の変更によって壊れることはありません。

たとえば、KMIインターフェイスで使用される構造にフィールドを追加する変更は、インターフェイス定義を変更するため、許可されていません。

struct foo {
  int original_field1;
  int original_field2;
  int new_field; // Not allowed
};

int do_foo(struct foo &myarg)
{
  do_something(myarg);
}
EXPORT_SYMBOL_GPL(do_foo);

ただし、新しい関数を追加することは問題ありません。

struct foo_ext {
  struct foo orig_foo;
  int new_field;
};

int do_foo2(struct foo_ext &myarg)
{
  do_something_else(myarg);
}
EXPORT_SYMBOL_GPL(do_foo2);

KMIの安定性

GKIの目標を実現するには、ドライバーの安定したKMIを維持することが重要です。 GKIカーネルはバイナリ形式で構築および出荷されますが、ベンダーがロード可能なモジュールは別のツリーで構築されます。結果として得られるGKIカーネルとモジュールは、一緒に構築されたかのように機能する必要があります。 GKI互換性テストでは、カーネルを含むブートイメージがGKIカーネルを含むブートイメージに置き換えられ、ベンダーイメージのロード可能なモジュールがどちらのカーネルでも正しく機能する必要があります。

KMIには、カーネル内のすべてのシンボル、または30,000以上のエクスポートされたシンボルのすべてが含まれているわけではありません。代わりに、モジュールで使用できるシンボルは、カーネルツリーのルートで公開されているシンボルリストファイルのセットに明示的にリストされています。すべてのシンボルリストファイル内のすべてのシンボルの和集合は、安定として維持されるKMIシンボルのセットを定義します。例シンボルリストファイルがあるabi_gki_aarch64_db845cに必要なシンボルを宣言し、 DragonBoardの845Cを

シンボルリストにリストされているシンボルとそれに関連する構造および定義のみがKMIの一部と見なされます。必要なシンボルが存在しない場合は、シンボルリストに変更を投稿できます。新しいインターフェイスがシンボルリストに含まれ、KMIの説明の一部になった後は、安定した状態に維持されるため、ブランチをフリーズした後でシンボルリストから削除したり変更したりしないでください。

各KMIカーネルツリーには、独自のシンボルリストのセットがあります。異なるKMIカーネルブランチ間でABIの安定性を提供する試みは行われません。たとえば、 android11-5.4のKMIは、 android11-5.4のKMIから完全に独立していandroid12-5.4

一般的に、Linuxコミュニティは、メインラインカーネルのカーネル内ABI安定性の概念に憤慨しています。さまざまなツールチェーン、構成、および進化し続けるLinuxメインラインカーネルに直面して、メインラインで安定したKMIを維持することは現実的ではありません。ただし、非常に制約のあるGKI環境では可能です。制約は次のとおりです。

  • KMIは、同じLTSカーネル(たとえば、 android11-5.4 )内でのみ安定しています。
    • android-mainline KMIの安定性は維持されません。
  • カーネルとモジュールの構築には、AOSPで提供され、対応するブランチ用に定義された特定のClangツールチェーンのみが使用されます。
  • シンボルリストで指定されているようにモジュールによって使用されることがわかっているシンボルのみが安定性について監視され、KMIシンボルと見なされます。
    • 当然の結果として、モジュールはKMIシンボルのみを使用する必要があります。これは、KMI以外のシンボルが必要な場合に、モジュールのロードに失敗することによって強制されます。
  • KMIブランチがフリーズした後は、次のような変更によってKMIが破損することはありません。
    • 構成の変更
    • カーネルコードの変更
    • ツールチェーンの変更(更新を含む)

KMIモニタリング

ABI監視ツールは、送信前テスト中にKMIの安定性を 監視します。 KMIに違反する変更は、送信前のテストに失敗するため、互換性を保つためにやり直す必要があります。これらのツールは、パートナーや一般の人々がビルドプロセスに統合するために利用できます。 Androidカーネルチームはこれらのツールを使用して、開発中およびLTSリリースのマージ時にKMIの破損を検出します。 LTSマージ中にKMIの破損が検出された場合、問題のあるパッチを削除するか、互換性があるようにパッチをリファクタリングすることにより、KMIが保持されます。

既存のKMIシンボルが互換性のない方法で変更された場合、KMIは壊れていると見なされます。例:

  • KMI関数に新しい引数が追加されました
  • KMI関数で使用される構造に新しいフィールドが追加されました
  • KMI関数で使用される列挙型の値を変更する新しい列挙型の値が追加されました
  • KMIに影響を与えるデータメンバーの存在を変更する構成の変更

新しいシンボルを追加しても、必ずしもKMIが破損するわけではありませんが、使用される新しいシンボルをシンボルリストとABI表現に追加する必要があります。そうしないと、KMIのこの部分に対する将来の変更が認識されません。

パートナーは、ABI監視ツールを使用して、製品カーネルとGKIカーネルの間でKMIを比較し、互換性があることを確認することが期待されています。

最新のandroid11-5.4バイナリGKIカーネルは、 ci.android.comkernel_aarch64ビルド)からダウンロードできます。

シングルコンパイラ

コンパイラを変更すると、ABIに影響を与える内部カーネルデータ構造のレイアウトが変更される可能性があります。 KMIを安定させることが重要であるため、GKIカーネルの構築に使用されるツールチェーンは、ベンダーモジュールの構築に使用されるツールチェーンと完全に互換性がある必要があります。 GKIカーネルは、AOSPに含まれているLLVMツールチェーンを使用して構築されています。

Android 10以降、すべてのAndroidカーネルはLLVMツールチェーンを使用して構築する必要があります。 GKIでは、製品カーネルとベンダーモジュールの構築に使用されるLLVMツールチェーンがAOSPからのLLVMツールチェーンと同じABIを生成する必要があり、パートナーはKMIがGKIカーネルと互換性があることを確認する必要があります。

Androidカーネルビルドドキュメントでは、リファレンスGKIカーネルのビルド方法について説明しています。特に、文書化された手順により、正しいツールチェーンと構成がカーネルの構築に使用されることが保証されます。ダウンストリームパートナーは、ツールチェーンやその他のビルド時の依存関係によって引き起こされる非互換性を回避するために、最終的なカーネルを生成するために同じツールを使用することをお勧めします。

カーネル構成

GKIカーネルは、 arch/arm64/configs/gki_defconfigを使用して構築されています。これらの構成はKMIに影響を与えるため、GKI構成は非常に慎重に管理されます。凍結されたKMIカーネルの場合、構成はKMIに影響がない場合にのみ追加または削除できます。

GKIカーネルは、さまざまなデバイスのセットで実行するように構成する必要があります。したがって、ハードウェアを有効にするために使用されるロード可能なモジュールを除く、これらすべてのデバイスに必要なすべてのサブシステムとオプションのサポートが組み込まれている必要があります。パートナーは開発カーネルに必要な構成変更要求する必要があります。

ブーツの変更

GKIコンポーネントとベンダーコンポーネントを明確に分離するために、 bootパーティションには、カーネルやGKIモジュールを備えたRAMディスクなどの汎用コンポーネントのみが含まれています。ブートヘッダーの新しいバージョン(v3)は、GKIアーキテクチャへの準拠を示すために定義されています。ブートイメージのGKIバージョンはGoogleによって提供され、GKIの互換性をテストするときに、ベンダーのバージョンのブートイメージを置き換えます。

第1段階のinitrecovery 、およびfastbootdのramdiskは、ブートローダーによって連結された2つのCPIOアーカイブで構成されるinitramfsイメージです。最初のCPIOアーカイブは、新しいvendor_bootパーティションから取得されます。 2つ目は、 bootパーティションからのものです。

変更の概要はここにあります。詳細については、ベンダーのブートパーティションを参照してください。

ブートパーティション

bootパーティションには、ヘッダー、カーネル、およびブートRAMディスクの汎用部分のCPIOアーカイブが含まれます。

ブートヘッダーv3 bootパーティションを使用すると、以前のbootパーティションのこれらのセクションは存在しなくなりboot

bootパーティションには、GKIコンポーネントを含むCPIOアーカイブが含まれています。

  • /lib/modules/あるGKIカーネルモジュール
  • first_stage_initとそれが依存するライブラリ
  • fastbootdおよびrecovery (A / Bおよび仮想A / Bデバイスで使用)

GKIブートイメージはGoogleから提供されており、 GKI互換性テストに使用する必要があります

最新arm64 android11-5.4 boot.imgからダウンロード可能ですci.android.comaosp_arm64のビルド成果物aosp-masterブランチ。

最新arm64 android11-5.4カーネルイメージ( Image.gz )からダウンロードすることができますci.android.comkernel_aarch64のビルド成果物aosp_kernel-common-android11-5.4ブランチ。

ベンダーのブートパーティション

vendor_bootパーティションはGKIで導入されました。これは仮想A / BでA / Bされ、ヘッダー、ベンダーRAMディスク、およびデバイスツリーブロブで構成されます。ベンダーRAMディスクは、デバイスの起動に必要なベンダーモジュールを含むCPIOアーカイブです。これには、重要なSoC機能を有効にするモジュールと、デバイスの起動とスプラッシュ画面の表示に必要なストレージおよびディスプレイドライバーが含まれます。

CPIOアーカイブには次のものが含まれます。

  • /lib/modules/ある第1段階のinitベンダーカーネルモジュール
  • /lib/modulesあるmodprobe設定ファイル
  • modules.loadファイルは、第1段階のinit中にロードするモジュールを示しinit

ブートローダーの要件

ブートローダーは、ベンダーのramdisk CPIOイメージ( vendor_bootパーティションから)の直後に、汎用のramdisk CPIOイメージ( bootパーティションから)をメモリにロードする必要があります。解凍後、結果はベンダーのRAMディスクのファイル構造の上にオーバーレイされた汎用RAMディスクです。

GKI互換性テスト

Android 11プラットフォームのリリースでは、v5.4カーネルで起動されたデバイスは、Googleが提供するGKIブートイメージを使用してVTSおよびCTS-on-GSIテストを実行する必要があります。

GKIカーネルへの貢献

GKIカーネルが始まるAOSP共通のカーネルから構築されていandroid11-5.4 。提出されたすべてのパッチは、 次の2つの戦略を文書化したこれらの貢献ガイドラインに準拠している必要があります。

  1. 最善:アップストリームLinuxにすべての変更を加えます。必要に応じて、安定版リリースにバックポートします。これらのパッチは、対応するAOSP共通カーネルに自動的にマージされます。パッチがすでにアップストリームLinuxにある場合は、以下のパッチ要件に準拠するパッチのバックポートを投稿してください。
  2. あまり良くない:(上流のLinuxの観点から)ツリーからパッチを開発します。パッチがAndroid固有のバグを修正していない限り、 kernel-team @ android.comと調整されていない限り、パッチが受け入れられる可能性はほとんどありません。

GKIを実装しているパートナーの場合、ツリー外のパッチが必要になる正当な理由がある可能性があります(特に、満たす必要のあるシリコンスケジュールがある場合)。このような場合は、 Buganizerの問題を報告してください

GKIの変更をGerritを介して最初にandroid-mainlineブランチに送信し、次に必要に応じて他のリリースブランチにバックポートします。

ロード可能なモジュールに関連付けられたソースコードをGKIカーネルソースツリーに提供する必要はありませんが、すべてのドライバーをアップストリームLinuxに送信することを強くお勧めします。

メインラインからのバックポートのリクエスト

通常、GKIパートナーが必要とするメインラインパッチは、GKIカーネルにバックポートできます。 投稿ガイドラインに従って、パッチをGerritにアップロードします

パッチがアップストリームに投稿されているが、まだ受け入れられていない場合は、受け入れられるまで待つことをお勧めします。パッチがアップストリームで受け入れられるのを待つことがスケジュールで許可されていない場合は、Buganizerの問題を報告してください。

GKI構成の追加と削除

arch/arm64/configs/gki_defconfigで構成の追加または削除をリクエストするには、リクエストと理由を明確に記載したBuganizerの問題を提出してください。アクセス可能なBuganizerプロジェクトがない場合は、構成を変更したパッチをGerritに投稿し、コミットメッセージに構成が必要な理由が明確に記載されていることを確認してください。

凍結されたKMIカーネルの構成変更は、KMIに影響を与えてはなりません。

コアカーネルコードの変更

AOSP共通カーネルのコアカーネルコードを変更することはお勧めしません。最初にパッチをアップストリームLinuxに送信し、次にそれらをバックポートします。コアカーネルの変更に正当な理由がある場合は、要求と正当化を明確に記載したBuganizerの問題を提出してください。 Buganizerの問題がなければ、Android固有の機能は受け入れられません。 Buganizerの問題を作成できない場合は、 kernel-team @ android.comにメールを送信してください。

EXPORT_SYMBOL_GPL()を介してを使用してシンボルをエクスポートする

シンボルのエクスポートのみを含むパッチをアップストリームに送信しないでください。アップストリームLinuxで考慮されるためには、 EXPORT_SYMBOL_GPL()追加には、シンボルを使用するツリー内モジュラードライバーが必要なので、エクスポートと同じパッチセットに新しいドライバーまたは既存のドライバーへの変更を含めます。

パッチをアップストリームに送信する場合、コミットメッセージには、パッチが必要であり、コミュニティにとって有益である理由を明確に説明する必要があります。ツリー外のドライバーまたは機能に利益をもたらすためにエクスポートを有効にすることは、アップストリームのメンテナにとって説得力のある議論ではありません。

何らかの理由でパッチをアップストリームに送信できない場合は、Buganizerの問題を報告し、パッチをアップストリームに送信できない理由を説明してください。一般に、カーネルサブシステムへのサポートされているインターフェイスであるシンボルは、エクスポートとして受け入れられる可能性があります。ただし、ランダムな内部ヘルパー関数が受け入れられる可能性は低く、それらを使用しないようにコードをリファクタリングするように求められます。

KMIシンボルリストへのシンボルの追加

KMIシンボルリストは、ベンダーモジュールで使用されるGKIカーネルシンボルで更新する必要があります。 KMIシンボルのみが安定して維持されるため、GKIは、モジュールが非KMIシンボルに依存している場合、モジュールのロードを許可しません。

extract_symbolsスクリプトは、カーネルビルドツリーから関連するシンボルを抽出し、KMIシンボルリストを更新するために使用できます。詳細については、 シンボルリストのドキュメントを参照してください。