GKI 版本管理架構

本頁面說明通用核心映像檔 (GKI) 的版本管理方案。通用核心映像檔 (GKI) 具有名為核心版本的專屬 ID。核心版本包含核心模組介面 (KMI) 版本和子層級。核心版本是指要發布的映像檔,而 KMI 版本則代表建構版本的介面。KMI 版本可支援多個核心版本。一個核心發布版本只會與一個 KMI 版本連結。在極少數的情況下,核心模組介面必須變更,KMI 產生作業會反覆進行,以反映 KMI 版本的變更。

條款摘要

下表列出本頁和 GKI 更新中使用的重點術語。

名稱 符號 示例 說明
核心發布版本 w.x.y-zzz-k-suffix 5.4.42-android12-0-foo GKI 版本的專屬 ID。這是 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 會直接用於整份文件。這也通常稱為三部分版本編號。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 欄位時,系統會從字串中擷取數字部分進行比較。

任何更新 (包括 OTA 或主線) 都不得降低 Android 版本號碼。

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。如果兩個 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)。

如果兩個核心版本具有相同的 KMI 版本,則會實作相同的核心模組介面。彼此相容的 DLKM 也彼此相容。

任何 OTA 更新都不得降低 KMI 版本。

子層

子層級 y 會說明相同 KMI 版本中核心版本的發布順序。

針對具有相同 KMI 版本,但有子層級 Y1 和 Y2 的兩個核心版本:

  • 如果 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 版本的 SHA 雜湊。

libkver

程式庫 libkver 提供 C++ 介面,可剖析核心版本或 KMI 版本字串。如需 libkver 公開的 API 清單,請參閱 packages/modules/Gki/libkver/include/kver

VINTF 檢查

對於 Android 11 以下版本,裝置製造商會在裝置資訊清單中手動指定 KMI 版本的 Android 版本部分。詳情請參閱「VINTF 核心比對規則」。

從 Android S 開始,KMI 版本的 Android 發布子集可從核心中擷取,並在建構期間插入裝置資訊清單。

由於核心設定需求通常不會變更,因此不需要在相容性矩陣中編碼 k。不過,如果確實需要變更核心設定需求,請務必確保以下事項:

  • 相容性矩陣中的對應需求也已移除。
  • 還會新增其他 VTS 測試,檢查 KMI 產生的新條件條件。

OTA 中繼資料中的啟動映像檔版本

即使啟動映像檔是透過 OTA 更新更新,也必須以 OTA 酬載格式 (payload.bin) 包裝。OTA 酬載會對每個分區的 version 欄位進行編碼。update_engine 處理 OTA 酬載時,會比較這個欄位,確保分區不會降級。

為避免混淆,OTA 中繼資料中啟動分區的 version 欄位稱為 boot image version

由於 ramdisk 一律是從頭開始建構,因此使用 ramdisk 時間戳記即可充分描述整個開機映像檔。除非您日後要將舊的啟動映像檔併接到新的核心二進位檔,否則不需要對啟動映像檔版本中的核心版本進行編碼。

在 OTA 更新之前,OTA 用戶端會以與其他分區相同的方式檢查啟動映像檔版本。