本頁說明通用核心映像檔 (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。 |
Sublevel | 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 | 這個詞彙用於 常見的 Kernel 分支類型。 |
版本 | 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 二進位檔的 Kernel 版本相同,則必須完全相同 (以位元組為單位)。
核心版本包含 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 相容的 DLKM 也會與另一個相容。
任何 OTA 更新都不得降低 KMI 版本。
Sublevel
子層級 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
的輸出內容會使用下列 regex 剖析 (假設 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 用戶端會以與其他任何分割區相同的方式,檢查開機映像檔版本。