本頁面說明通用核心映像檔 (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 (甜點) 版本號碼。
比較 任何更新 (包括 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 用戶端會以與其他分區相同的方式檢查啟動映像檔版本。