Android カーネル ABI のモニタリング

Android 11 以降で利用可能なアプリケーション バイナリ インターフェース(ABI)モニタリング ツールを使用して、Android カーネルのカーネル内 ABI を安定させることができます。このツールは、既存のカーネル バイナリ(vmlinux + モジュール)から ABI 表現を収集して比較します。これらの ABI 表現は、.stg ファイルとシンボルリストです。この表現がビューを提供するインターフェースを、カーネル モジュール インターフェース(KMI)といいます。このツールを使用すれば、KMI の変更を追跡し、軽減できます。

ABI モニタリング ツールは AOSP で開発されたもので、STG(または Android 13 以前では libabigail)を使用して表現を生成し、比較します。

このページでは、このツールや、ABI 表現の収集と分析のプロセス、カーネル内 ABI を安定させるための ABI 表現の使用方法について説明します。また、Android カーネルの変更に貢献するための情報も提供します。

プロセス

カーネルの ABI を分析するには複数のステップが必要ですが、そのほとんどは自動化できます。

  1. カーネルとその ABI 表現をビルドする
  2. ビルドと参照の間で ABI の違いを分析する
  3. ABI 表現を更新する(必要な場合)
  4. シンボルリストを使用する

以下の手順は、サポートされているツールチェーン(ビルド済みの Clang ツールチェーンなど)を使用してビルドできるカーネルの場合に使用できます。repo manifests は、すべての Android 共通カーネル ブランチと複数のデバイス固有カーネルで使用できます。これにより、分析用のカーネル ディストリビューションをビルドするときに正しいツールチェーンが使用されるようになります。

シンボルリスト

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

シンボルリストにリストされているシンボルと、関連する構造および定義のみが、KMI の一部とみなされます。必要なシンボルが存在しない場合は、シンボルリストの変更を送信できます。新しいインターフェースがシンボルリストに含まれると、KMI の一部として記載され、安定版として維持されます。ブランチが固定された後でシンボルリストから削除または変更されることはありません。

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

ABI ツールは、KMI シンボルリストを使用して、安定性のモニタリングが必要となるインターフェースを限定します。メイン シンボルリストには、GKI カーネル モジュールで必要なシンボルが含まれています。ベンダーは、使用するインターフェースが ABI の互換性を維持できるように、追加のシンボルリストを送信して更新する必要があります。たとえば、android13-5.15 のシンボルリストのリストについては、https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15/android をご覧ください。

シンボルリストには、特定のベンダーまたはデバイスに必要と報告されたシンボルが含まれています。ツールで使用されるシンボルの完全なリストは、すべての KMI シンボルリスト ファイルを結合したものです。ABI ツールにより、関数のシグネチャやネストされたデータ構造など、各シンボルの詳細が決定されます。

KMI が固定された場合でも、既存の KMI インターフェースに変更を加えることはできません。これらは安定しています。ただし、既存の ABI の安定性に影響しない限り、KMI にはいつでも自由にシンボルを追加できます。新しく追加されたシンボルは、KMI シンボルリストで引用されるとすぐに安定版として維持されます。シンボルは、そのシンボルに依存するデバイスが出荷されていないことを確認できた場合を除き、カーネルのリストから削除しないでください。

デバイスの KMI シンボルリストは、シンボルリストの使用方法の手順に沿って生成できます。多くのパートナーは、ACK ごとに 1 つのシンボルリストを送信しますが、これは厳格な要件ではありません。メンテナンスに役立つ場合は、複数のシンボルリストを送信できます。

KMI を拡張する

KMI シンボルと関連構造は安定版として維持されます(つまり、固定された KMI があるカーネルにおいて安定したインターフェースを破壊する変更は認められません)。その一方で、GKI カーネルは拡張可能なままであるため、年内後半に出荷されるデバイスでは、KMI が固定される前にすべての依存関係を定義する必要はありません。KMI を拡張するには、新規または既存のエクスポートされたカーネル関数の KMI に新しいシンボルを追加します。この処理は KMI が固定されている場合でも可能です。KMI の互換性が損なわれなければ、新しいカーネルパッチも使用できます。

KMI の互換性の問題について

カーネルにはソースがあり、それらのソースに基づいてバイナリがビルドされます。 ABI のモニタリング対象のカーネル ブランチには、現在の GKI ABI を表現する abi.xml が含まれています。バイナリをビルドすると(カーネル バイナリ、vmlinuxImage とカーネル モジュール)、バイナリから abi.xml ファイルを抽出できるようになります。カーネルソースに変更を加えるとバイナリが変更され、抽出された abi.xml(変更を適用してカーネルをビルドした後に抽出されるファイル)も変更される場合があります。AbiAnalyzer アナライザは、2 つの abi.xml ファイルを意味的に比較し、問題が見つかった場合に Lint-1 ラベルを設定します。

ABI の互換性の問題を処理する

一例として、次のパッチは非常に明白な ABI の互換性の問題をもたらします。

 diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
  index 5ed8f6292a53..f2ecb34c7645 100644
  --- a/include/linux/mm_types.h
  +++ b/include/linux/mm_types.h
  @@ -339,6 +339,7 @@ struct core_state {
   struct kioctx_table;
   struct mm_struct {
      struct {
  +       int dummy;
          struct vm_area_struct *mmap;            /* list of VMAs */
          struct rb_root mm_rb;
          u64 vmacache_seqnum;                   /* per-thread vmacache */

このパッチを適用してビルド ABI を実行すると、ツールはゼロ以外のエラーコードで終了し、次のような ABI の違いを報告します。

 Leaf changes summary: 1 artifact changed
  Changed leaf types summary: 1 leaf type changed
  Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 0 Added function
  Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable

  'struct mm_struct at mm_types.h:372:1' changed:
    type size changed from 6848 to 6912 (in bits)
    there are data member changes:
  [...]

ビルド時に検出された ABI の違い

エラーの最も一般的な理由は、ドライバがカーネルのシンボルリストにない新しいシンボルを使用していることです。

シンボルがシンボルリスト(android/abi_gki_aarch64)に含まれていない場合は、最初にそのシンボルが EXPORT_SYMBOL_GPL(symbol_name) でエクスポートされていることを確認してから、ABI XML 表現とシンボルを更新する必要があります。たとえば、次の変更を行うと、新しい増分 FS 機能が android-12-5.10 ブランチに追加され、シンボルリストと ABI XML 表現が更新されます。

シンボルがエクスポートされていて(ユーザーがエクスポートしたか、以前にエクスポート済みである)、現在他のドライバによって使用されていない場合、次のようなビルドエラーが発生する可能性があります。

Comparing the KMI and the symbol lists:
+ build/abi/compare_to_symbol_list out/$BRANCH/common/Module.symvers out/$BRANCH/common/abi_symbollist.raw
ERROR: Differences between ksymtab and symbol list detected!
Symbols missing from ksymtab:
Symbols missing from symbol list:
 - simple_strtoull

この問題を解決するには、カーネルと ACK の両方で KMI シンボルリストを更新します(ABI 表現を更新するをご覧ください)。ACK 内の ABI XML とシンボルリストを更新する例については、aosp/1367601 を参照してください。

カーネル ABI の互換性の問題を解決する

カーネル ABI の互換性の問題に対処するには、ABI を変更しないようにコードをリファクタリングするか、ABI 表現を更新します。次の図を参考に、現在の状況に最適な方法を決定してください。

ABI の互換性の問題のフローチャート

図 1. ABI の互換性の問題の解決

コードをリファクタリングして ABI の変更を回避する

既存の ABI が変更されないようにします。多くの場合、コードをリファクタリングすると、ABI に影響する変更を削除できます。

  • 構造体フィールドの変更をリファクタリングする。変更によりデバッグ機能の ABI を変更する場合は、フィールド(構造体とソースの参照)を囲む #ifdef を追加し、#ifdef に使用する CONFIG が本番環境の defconfig と gki_defconfig で無効になるようにします。ABI の互換性を損なうことなくデバッグ構成を構造体に追加する方法の例については、このパッチセットをご覧ください。

  • コアカーネルを変更しないように機能をリファクタリングする。パートナー モジュールをサポートするために新しい機能を ACK に追加する必要がある場合は、カーネル ABI の変更を回避するために、変更の ABI 部分をリファクタリングしてください。カーネル ABI を変更せずに既存のカーネル ABI を使用して機能を追加する例については、aosp/1312213 をご覧ください。

互換性が損なわれた ABI を Android Gerrit で修正する

カーネル ABI の互換性を意図的に損なったのでなければ、ABI モニタリング ツールで提供されるガイダンスに沿って調査する必要があります。互換性の問題の原因としてありがちなものは、関数の追加や削除、データ構造の変更、またはそのいずれかにつながる構成オプションの追加による ABI の変更です。まずは、ツールで見つかった問題に対処します。

ABI の結果をローカルで再現できます。カーネルとその ABI 表現をビルドするをご覧ください。

Lint-1 ラベルについて

固定 KMI または確定済み KMI を含むブランチに変更をアップロードする場合、その変更では、互換性のない形で安定版 ABI に影響しないように、ABIAnalyzer を渡す必要があります。このプロセスでは、ABIAnalyzer はビルド時に作成される ABI レポートを探します(通常のビルドと ABI の抽出および比較の各ステップを実行する拡張ビルド)。 ABIAnalyzer が空ではないレポートを検出すると、Lint-1 ラベルが設定され、解決される(パッチセットが Lint+1 ラベルを受け取る)までは変更を送信できなくなります。

カーネル ABI を更新する

ABI の変更が避けられない場合は、コードの変更、ABI 表現、シンボルリストを ACK に適用する必要があります。GKI の互換性を損なわずに Lint-1 ラベルを受け取らないようにするには、次の手順を行います。

  1. コードの変更を ACK にアップロードします

  2. パッチセットのコードレビュー +2 を受け取るまで待ちます。

  3. 参照 ABI 表現を更新します

  4. コードの変更と ABI の更新の変更を統合します。

ABI コードの変更を ACK にアップロードする

ACK ABI を更新する方法は、変更の種類によって異なります。

  • ABI の変更が CTS テストまたは VTS テストに影響する機能に関連する場合、通常はその変更をそのまま ACK で選べます。次に例を示します。

    • 音声が機能するには aosp/1289677 が必要です。
    • USB が機能するには、aosp/1295945 が必要です。
  • ABI の変更が ACK と共有可能な機能に対するものである場合、その変更をそのまま ACK で選べます。たとえば、以下の変更は CTS テストや VTS テストでは必要ありませんが、ACK で共有しても問題ありません。

  • ABI の変更により、ACK に含める必要のない新機能が導入された場合は、次のセクションで説明するように、スタブを使用してシンボルを ACK に導入できます。

ACK にスタブを使用する

スタブは、パフォーマンスや電源の変更など、ACK にメリットがないコアカーネルの変更にのみ必要です。以下では、GKI の ACK でのスタブと部分的な選択の例を示します。

  • コア分離機能スタブ(aosp/1284493)。この機能は ACK では必須ではありませんが、モジュールでシンボルを使用するには、そのシンボルが ACK に存在する必要があります。

  • ベンダー モジュールのプレースホルダ シンボル(aosp/1288860)。

  • プロセスごとの mm イベント トラッキング機能の ABI のみの選択(aosp/1288454)。元のパッチは ACK で選択され、task_structmm_event_count の ABI 差分の解決に必要な変更のみが含まれています。このパッチは、最終メンバーを含むように mm_event_type 列挙型も更新します。

  • 新しい ABI フィールドの追加以外の操作も必要となる熱的構造体 ABI の変更を部分的に選択しました。

    • パッチ aosp/1255544 はパートナー カーネルと ACK の間の ABI の違いを解決しました。

    • パッチ aosp/1291018 は以前のパッチの GKI テスト中に見つかった機能に関する問題を修正しました。この修正には、複数の温度帯を単一のセンサーに登録するようにセンサー パラメータ構造体を初期化することも含まれていました。

  • CONFIG_NL80211_TESTMODE ABI の変更(aosp/1344321)。このパッチにより、ABI に必要な構造体の変更が追加され、追加されたフィールドにより機能面の差異が生じないようになりました。これにより、パートナーが本番環境カーネルに CONFIG_NL80211_TESTMODE を組み込み、GKI のコンプライアンスを維持できるようになりました。

実行時に KMI を適用する

GKI カーネルは TRIM_UNUSED_KSYMS=y 構成オプションと UNUSED_KSYMS_WHITELIST=<union of all symbol lists> 構成オプションを使用して、エクスポートされるシンボル(EXPORT_SYMBOL_GPL() を使用してエクスポートされるシンボルなど)をシンボルリストにあるものに限定します。その他のシンボルはすべてエクスポートされません。また、エクスポートされていないシンボルを必要とするモジュールの読み込みは拒否されます。この制限はビルド時に適用され、欠落しているエントリにはフラグが設定されます。

開発には、シンボルをカットしない GKI カーネルビルドを使用できます(つまり、通常エクスポートされるシンボルはすべて使用できます)。これらのビルドを見つけるには、ci.android.comkernel_debug_aarch64 ビルドを探します。

モジュール バージョニングを使用して KMI を適用する

汎用カーネル イメージ(GKI)カーネルは、実行時に KMI コンプライアンスを適用するための追加の手段として、モジュール バージョニングCONFIG_MODVERSIONS)を使用します。モジュール バージョニングでは、モジュールの予想される KMI が vmlinux KMI と一致しない場合、モジュール読み込み時に巡回冗長検査(CRC)の不一致エラーが発生することがあります。シンボル module_layout() の CRC 不一致によりモジュール読み込み時に発生する一般的なエラーの例を次に示します。

init: Loading module /lib/modules/kernel/.../XXX.ko with args ""
XXX: disagrees about version of symbol module_layout
init: Failed to insmod '/lib/modules/kernel/.../XXX.ko' with args ''

モジュール バージョニングの使用

モジュール バージョニングが有用である理由として、次の点が挙げられます。

  • モジュール バージョニングは、データ構造の公開設定の変更を捕捉します。モジュールが不透明なデータ構造、つまり KMI に含まれないデータ構造を変更する場合、将来的に構造が変更されるとモジュールの互換性が破られます。

    例として、struct devicefwnode フィールドについて考えてみましょう。このフィールドは、device->fw_node のフィールドを変更したり、そのサイズについて推測したりできないように、モジュールに対して不透明でなければなりません。

    ただし、モジュールに <linux/fwnode.h> が(直接的または間接的に)含まれている場合、struct devicefwnode フィールドは不透明でなくなります。すると、モジュールは device->fwnode->dev または device->fwnode->ops を変更できます。このシナリオには次のような理由から、問題があります。

    • コアカーネル コードで内部データ構造に対して行っている仮定が破られる可能性があります。

    • 将来のカーネル更新で struct fwnode_handlefwnode のデータ型)が変更された場合、モジュールが新しいカーネルで機能しなくなります。さらに、バイナリ表現の検査だけでは捕捉できない方法で内部データ構造を直接操作して KMI の互換性を破るため、abidiff は違いを示しません。

  • 現在のモジュールが後日、互換性のない新しいカーネルによって読み込まれた場合、KMI 互換でないとみなされます。カーネルと KMI 互換でないモジュールを誤って読み込まないように、モジュール バージョニングではランタイム チェックが追加されます。このチェックは、KMI で検出されない非互換性によって発生する、デバッグが困難なランタイムの問題やカーネル クラッシュを防ぎます。

  • abidiff には、CONFIG_MODVERSIONS が捕捉できる特定の複雑なケースで、ABI の違いを特定する際に制限があります。

モジュール バージョニングを有効にすると、このような問題をすべて回避できます。

デバイスを起動せずに CRC 不一致を確認する

abidiff は、カーネル間の CRC 不一致を比較して報告します。このツールを使用すると、他の ABI の違いと同時に、CRC 不一致を検出できます。

また、CONFIG_MODVERSIONS が有効になっている完全なカーネルビルドは、通常のビルドプロセスの一環として Module.symvers ファイルを生成します。このファイルの行は、カーネル(vmlinux)とモジュールによってエクスポートされるシンボルごとに 1 行ずつです。各行は、CRC 値、シンボル名、シンボル名前空間、シンボルをエクスポートしている vmlinux またはモジュール名、エクスポート タイプ(EXPORT_SYMBOLEXPORT_SYMBOL_GPL など)で構成されています。

GKI ビルドとお使いのビルドの間で Module.symvers ファイルを比較して、vmlinux によってエクスポートされたシンボルの CRC の違いを確認できます。vmlinux によってエクスポートされたシンボルに CRC 値の違いがあり、かつ、そのシンボルがデバイスに読み込むモジュールのいずれかで使用されている場合、そのモジュールは読み込まれません。

ビルド アーティファクトがすべてあるわけでなく、GKI カーネルとカーネルの vmlinux ファイルがあるだけの場合は、両方のカーネルで次のコマンドを実行し、出力を比較することで、特定のシンボルの CRC 値を比較できます。

nm <path to vmlinux>/vmlinux | grep __crc_<symbol name>

たとえば、次のコマンドは、module_layout シンボルの CRC 値を確認します。

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

CRC 不一致を解決する

モジュールの読み込み時に発生した CRC 不一致を解決する方法は次のとおりです。

  1. 次のコマンドに示すように --kbuild_symtypes オプションを使用して、GKI カーネルとデバイス カーネルをビルドします。

    tools/bazel run --kbuild_symtypes //common:kernel_aarch64_dist
    

    このコマンドにより、.o ファイルごとに .symtypes ファイルが生成されます。詳しくは、Kleaf の KBUILD_SYMTYPES をご覧ください。

    Android 13 以前の場合は、次のコマンドに示すように、カーネルのビルドに使用するコマンドの先頭に KBUILD_SYMTYPES=1 を追加して、GKI カーネルとデバイス カーネルをビルドします。

    KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
    

    build_abi.sh, を使用する場合、KBUILD_SYMTYPES=1 フラグはすでに暗黙的に設定されています。

  2. 次のコマンドを使用して、CRC 不一致のシンボルがエクスポートされている .c ファイルを探します。

    cd common && git grep EXPORT_SYMBOL.*module_layout
    kernel/module.c:EXPORT_SYMBOL(module_layout);
    
  3. この .c ファイルには、GKI 内の対応する .symtypes ファイルと、デバイス カーネルのビルド アーティファクトが含まれます。次のコマンドを使用して .c ファイルを見つけます。

    cd out/$BRANCH/common && ls -1 kernel/module.*
    kernel/module.o
    kernel/module.o.symversions
    kernel/module.symtypes
    

    .c ファイルの特性は次のとおりです。

    • .c ファイルの形式は、シンボルごとに 1 行です(非常に長い場合もあります)。

    • 行頭の [s|u|e|etc]# は、シンボルがデータ型 [struct|union|enum|etc] であることを示しています。次に例を示します。

      t#bool typedef _Bool bool
      
    • 行頭に # プレフィックスがない場合は、シンボルが関数であることを示しています。次に例を示します。

      find_module s#module * find_module ( const char * )
      
  4. 2 つのファイルを比較し、違いをすべて修正します。

ケース 1: データ型の表示による違い

一方のカーネルがモジュールに対してシンボルまたはデータ型を不透明にし、他方のカーネルはそうでない場合、その違いは 2 つのカーネルの .symtypes ファイルの間に現れます。一方のカーネルの .symtypes ファイルにはシンボルの UNKNOWN があり、他方のカーネルの .symtypes ファイルにはシンボルまたはデータ型の展開ビューがあります。

たとえば、カーネルの include/linux/device.h ファイルに次の行を追加すると、CRC 不一致が発生します。そのうちの 1 つは module_layout() のものです。

 #include <linux/fwnode.h>

そのシンボルの module.symtypes を比較すると、次のような違いが表示されます。

 $ diff -u <GKI>/kernel/module.symtypes <your kernel>/kernel/module.symtypes
  --- <GKI>/kernel/module.symtypes
  +++ <your kernel>/kernel/module.symtypes
  @@ -334,12 +334,15 @@
  ...
  -s#fwnode_handle struct fwnode_handle { UNKNOWN }
  +s#fwnode_reference_args struct fwnode_reference_args { s#fwnode_handle * fwnode ; unsigned int nargs ; t#u64 args [ 8 ] ; }
  ...

カーネルに UNKNOWN の値があり、GKI カーネルにシンボルの展開ビューがある場合(ほとんどありません)は、最新の Android 共通カーネルをカーネルに統合して、最新の GKI カーネルベースを使用できるようにします。

ほとんどの場合、GKI カーネルには UNKNOWN の値がありますが、カーネルに加えられた変更により、カーネルにはシンボルの内部詳細があります。これは、カーネルのファイルのいずれかが、GKI カーネルには存在しない #include を追加したためです。

違いの原因となっている #include を特定する手順は次のとおりです。

  1. 違いがあるシンボルまたはデータ型を定義しているヘッダー ファイルを開きます。たとえば struct fwnode_handle の場合は include/linux/fwnode.h を編集します。

  2. ヘッダー ファイルの先頭に次のコードを追加します。

    #ifdef CRC_CATCH
    #error "Included from here"
    #endif
    
  3. CRC 不一致があるモジュールの .c ファイルで、#include 行より前に、次の行を最初の行として追加します。

    #define CRC_CATCH 1
    
  4. モジュールをコンパイルします。結果のビルド時エラーは、この CRC 不一致の原因となったヘッダー ファイル #include のチェーンを示しています。次に例を示します。

    In file included from .../drivers/clk/XXX.c:16:`
    In file included from .../include/linux/of_device.h:5:
    In file included from .../include/linux/cpu.h:17:
    In file included from .../include/linux/node.h:18:
    .../include/linux/device.h:16:2: error: "Included from here"
    #error "Included from here"
    

    #include のチェーン内のリンクの 1 つは、カーネルで行われた変更によるものであり、GKI カーネルにはありません。

  5. 変更を確認して、カーネルで元に戻すか、ACK にアップロードして統合します

ケース 2: データ型の変更による違い

シンボルまたはデータ型の CRC 不一致が表示の違いによるものではない場合は、データ型自体が実際に変更(追加、削除、または変更)されたことによるものです。これは通常 abidiff が捕捉しますが、既知の検出ギャップが原因で見逃された場合は MODVERSIONS メカニズムが捕捉します。

たとえば、カーネルに次の変更を加えると、多くのシンボルがこの種の変更によって間接的に影響を受けるため、いくつかの CRC 不一致が発生します。

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
  --- a/include/linux/iommu.h
  +++ b/include/linux/iommu.h
  @@ -259,7 +259,7 @@ struct iommu_ops {
     void (*iotlb_sync)(struct iommu_domain *domain);
     phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
     phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain,
  -        dma_addr_t iova);
  +        dma_addr_t iova, unsigned long trans_flag);
     int (*add_device)(struct device *dev);
     void (*remove_device)(struct device *dev);
     struct iommu_group *(*device_group)(struct device *dev);

そのうちの 1 つの CRC 不一致は devm_of_platform_populate() のものです。

そのシンボルの .symtypes ファイルを比較すると、次のようになります。

 $ diff -u <GKI>/drivers/of/platform.symtypes <your kernel>/drivers/of/platform.symtypes
  --- <GKI>/drivers/of/platform.symtypes
  +++ <your kernel>/drivers/of/platform.symtypes
  @@ -399,7 +399,7 @@
  ...
  -s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t ) ; int
    ( * add_device ) ( s#device * ) ; ...
  +s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t , unsigned long ) ; int ( * add_device ) ( s#device * ) ; ...

変更された型を特定する方法は次のとおりです。

  1. ソースコード(通常は .h ファイル)内でシンボルの定義を探します。

    • お使いのカーネルと GKI カーネルの間のシンプルなシンボルの違いを確認するには、次のコマンドを実行してコミットを見つけます。
    git blame
    
    • 削除されたシンボルを確認するには(一方のツリーでシンボルが削除され、それを他方のツリーでも削除したい場合)、その行を削除した変更を見つける必要があります。行が削除されたツリーで、次のコマンドを使用します。
    git log -S "copy paste of deleted line/word" -- <file where it was deleted>
    
  2. 返されたコミットのリストを確認し、変更または削除を見つけます。最初のコミットが、探していたもののはずです。そうでなければ、コミットが見つかるまでリストを探してください。

  3. 変更を確認したら、カーネルで元に戻すか、ACK にアップロードして統合します