GKI のバージョニング

このページでは、汎用カーネル イメージ(GKI)のバージョニング スキームについて説明します。汎用カーネル イメージ(GKI)にはカーネル リリースと呼ばれる一意の識別子があります。カーネル リリースは、カーネル モジュール インターフェース(KMI)のバージョンとサブレベルで構成されます。カーネル リリースはリリースされるイメージに固有のものであるのに対し、KMI バージョンはリリースがビルドされるインターフェースを表します。KMI バージョンは複数のカーネル リリースをサポートできますが、カーネル リリースは 1 つの KMI バージョンにのみ関連付けられます。万が一、カーネル モジュール インターフェースを変更する必要がある場合、KMI バージョンの変更を反映するために KMI 世代が反復処理されます。

用語の概要

次の表は、このページおよび GKI の更新で使用される重要な用語をまとめたものです。

名前 記号 説明
カーネル リリース w.x.y-zzz-k-suffix 5.4.42-android12-0-foo GKI リリースの一意の識別子。これは uname で返される値です。
KMI バージョン w.x-zzz-k 5.4-android12-0 GKI とダイナミック ローダブル カーネル モジュール(DLKM)の間のカーネル モジュール インターフェース(KMI)を表します。
サブレベル y 42 同じ KMI バージョン内のカーネル リリースのリリース順序を表します。

次の表に、その他の関連する用語をリファレンスとして示します。

名前 記号 説明
w.x.y w.x.y 5.4.42

詳しくは、Linux カーネルの Makefile をご覧ください(「KERNELRELEASE」を検索)。

このドキュメント全体を通して、w.x.y をそのまま使用しています。これは一般に、「3 つのパートから構成されるバージョン番号」とも呼ばれます。VINTF で使用される用語の「カーネル バージョン」は、他の用語、特に w と混同される可能性があります。

この変数は、libkver では kernel_version_tuple と表記されます。

このタプルは、OTA やメインラインなどのアップデートで下げることはできません。

カーネル ブランチ zzz-w.x android12-5.4 この用語は、共通カーネル ブランチ タイプで使用されます。
バージョン w 5 この用語は、このドキュメントでは使用されません。この変数は、libkver では version と表記されます。
パッチレベル x 4 この用語は、このドキュメントでは使用されません。この変数は、libkver では patch_level と表記されます。
Android リリース zzz android12

これは、カーネルが関連付けられている Android(デザート名)リリース番号です。

AndroidRelease フィールドを比較する際に、数値部分が文字列から抽出されて比較されます。

Android のリリース番号は、OTA やメインラインなどのアップデートで下げることはできません。

KMI 世代 k 0

これは、めったに発生しないイベントに対応するための追加の数値です。セキュリティ バグの修正により同じ Android リリース内で KMI を変更する必要が生じた場合は、KMI 世代が上がります。

KMI 世代番号は 0 から始まります。

バージョニングの設計

カーネル リリース

定義

GKI が搭載されたデバイスの場合、カーネル リリースは次のように定義されます。

KernelRelease :=
Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix
w      .x         .y       -zzz           -k            -something

詳細については、デバイスでカーネル リリースを確認するをご覧ください。

カーネル リリースの例を次に示します。

5.4.42-android12-0-00544-ged21d463f856

説明

カーネル リリースは、GKI リリースの一意の ID です。2 つの GKI バイナリのカーネル リリースが同じ場合は、バイト単位で同一である必要があります。

カーネル リリースは、KMI バージョン、サブレベル、サフィックスで構成されます。このドキュメントでは、KMI 世代の後ろのサフィックスは無視します。

KMI バージョン

定義

KMI バージョンは次のように定義されます。

KmiVersion :=
Version.PatchLevel-AndroidRelease-KmiGeneration
w      .x         -zzz           -k

サブレベルの y は KMI バージョンには含まれません。カーネル リリースの例の場合、KMI バージョンは次のようになります。

5.4-android12-0

説明

KMI バージョンは、GKI とダイナミック ローダブル カーネル モジュール(DLKM)の間のカーネル モジュール インターフェース(KMI)を表します。

2 つのカーネル リリースが同じ KMI バージョンを持つ場合、これらは同じカーネル モジュール インターフェースを実装しています。1 つのカーネル リリースと互換性のある DLKM は、もう 1 つのカーネル リリースとも互換性があります。

OTA アップデートによって KMI バージョンを下げることはできません。

サブレベル

サブレベルの y は、同じ KMI バージョン内のカーネル リリースのリリース順序を表します。

KMI バージョンが同じで、サブレベルがそれぞれ Y1 と Y2 である 2 つのカーネル リリースの場合、次のようになります。

  • Y1 が Y2 以下の場合、Y1 を搭載したデバイスは Y2 のアップデートを受信できます。
  • Y1 が Y2 より大きい場合、Y1 を搭載したデバイスは Y2 にアップデートできません。

つまり、KMI バージョンが変わらない場合、OTA アップデートによってサブレベルを下げることはできません。

デバイスでカーネル リリースを確認する

完全なカーネル リリースを確認するには、uname -r を実行するか、または次のコード スニペットで uname(2) を実行します。

std::string get_kernel_release() {
  struct utsname buf;
  return uname(&buf) == 0 ? buf.release : "";
}

出力例:

5.4.42-android12-0-00544-ged21d463f856

このドキュメントでは、KMI 世代の後ろの情報はすべて、カーネル情報の抽出時に無視します。より正式には、uname -r の出力は次の正規表現で解析されます(zzz が常に「android」で始まる場合)。

^(?P<w>\d+)[.](?P<x>\d+)[.](?P<y>\d+)-(?P<z>android\d+)-(?P<k>\d+).*$

無視される情報には、ci.android.com のビルド番号、ベースライン カーネル上のパッチの数、git commit の SHA ハッシュなどがあります。

libkver

ライブラリ libkver には、カーネル リリースや KMI バージョンの文字列を解析するための C++ インターフェースが用意されています。libkver が公開する API のリストについては、packages/modules/Gki/libkver/include/kver をご覧ください。

VINTF チェック

Android 11 以前の場合、KMI バージョンの Android リリース部分は、デバイス メーカーがデバイス マニフェストで手動で指定します。詳細については、VINTF カーネルのマッチング ルールをご覧ください。

Android S 以降では、KMI バージョンの Android リリース部分をカーネルから抽出して、ビルド時にデバイス マニフェストに挿入できます。

通常はカーネル構成要件を変更することはないため、互換性マトリックス内で k をエンコードする必要はありません。ただし、万が一カーネル構成要件を変更する必要がある場合は、次の点を確認してください。

  • 互換性マトリックスから対応する要件が削除されている。
  • KMI 世代を条件とする新しい要件をチェックするための VTS テストが追加されている。

OTA メタデータ内のブートイメージ バージョン

ブートイメージが OTA アップデートにより更新された場合でも、OTA ペイロード形式 payload.bin でラップする必要があります。OTA ペイロードは、各パーティションの version フィールドをエンコードします。update_engine は、OTA ペイロードを処理するときに、このフィールドを比較して、パーティションがダウングレードされないようにします。

混乱を避けるために、OTA メタデータのブート パーティションの version フィールドは boot image version と呼ばれます。

RAM ディスクは常にゼロから作成されるため、RAM ディスクのタイムスタンプを使用するだけでブートイメージ全体を記述できます。将来的に古いブートイメージを新しいカーネル バイナリに合成する場合を除き、ブートイメージ バージョンでカーネル リリースをエンコードする必要はありません。

OTA アップデートの前に、OTA クライアントは他のパーティションと同じ方法でブートイメージのバージョンをチェックします。