如要在新裝置上導入虛擬 A/B 測試,或在已發布的裝置上進行改造,您必須變更裝置專屬的程式碼。
建構旗標
使用虛擬 A/B 的裝置必須設定為 A/B 裝置,且必須使用動態分割區啟動。
如要使用虛擬 A/B 功能啟動裝置,請將裝置設為繼承虛擬 A/B 裝置基本設定:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
使用虛擬 A/B 啟動的裝置只需要一半的電路板大小,即可容納 BOARD_SUPER_PARTITION_SIZE
,因為 B 插槽不再位於超級插槽中。也就是說,BOARD_SUPER_PARTITION_SIZE
必須大於或等於 sum(更新群組大小) + 額外負荷,而這又必須大於或等於 sum(分割區大小) + 額外負荷。
如要使用 Virtual A/B 啟用壓縮快照 (適用於 Android 13 以上版本),請沿用下列基本設定:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/vabc_features.mk)
這樣一來,使用者就能搭配 Virtual A/B 使用使用者空間快照,同時採用無運算壓縮方法。然後將壓縮方法設定為其中一種支援的方法,zstd
和 lz4
。在 Android 15 中,壓縮作業可進一步自訂,以符合裝置需求。詳情請參閱「微調壓縮」。
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536
如果是 Android 12,如要透過 Virtual A/B 啟用壓縮快照,請沿用下列基本設定:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
XOR 壓縮
如果裝置升級至 Android 13 以上版本,XOR 壓縮功能不會預設啟用。如要啟用 XOR 壓縮,請在裝置的 .mk
檔案中新增以下內容。
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
對於從 android_t_baseline.mk
繼承的裝置,XOR 壓縮功能預設為啟用。
使用者空間合併
在 Virtual A/B 的新版 (Android T 以上版本) 中,快照合併程序完全在使用者空間中進行。這項變更是由 snapuserd 和 dm-user 促成。搭載 Android 13 以上版本的裝置預設會啟用使用者空間合併功能,而升級的舊版裝置則可透過下列方式設定這項屬性:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
啟動控制 HAL
開機控制 HAL 提供介面,供 OTA 用戶端控制開機插槽。虛擬 A/B 需要升級啟動控制 HAL 的次要版本,因為需要額外的 API,才能確保在刷機或恢復原廠設定期間保護啟動載入程式。如要查看最新版 HAL 定義,請參閱 IBootControl.hal 和 types.hal。
// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };
// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
setSnapshotMergeStatus(MergeStatus status)
generates (bool success);
getSnapshotMergeStatus()
generates (MergeStatus status);
}
// Recommended implementation
Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
// Write value to persistent storage
// e.g. misc partition (using libbootloader_message)
// bootloader rejects wipe when status is SNAPSHOTTED
// or MERGING
}
Fstab 變更
中繼資料分割區的完整性對啟動程序至關重要,尤其是在套用 OTA 更新後。因此,中繼資料分割區必須先經過檢查,first_stage_init
才能掛接。如要確保發生這種情況,請將 check
fs_mgr 標記新增至 /metadata
的項目。以下提供範例:
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check
核心需求
如要啟用快照功能,請將 CONFIG_DM_SNAPSHOT
設為 true
。
如果裝置使用 F2FS,請加入 f2fs:將 FS_NOCOW_FL 旗標匯出至使用者核心修補程式,修正檔案釘選問題。請一併納入 f2fs:支援對齊的釘選檔案核心修補程式。
虛擬 A/B 測試依賴核心 4.3 版新增的功能:snapshot
和 snapshot-merge
目標中的溢位狀態位元。所有搭載 Android 9 以上版本的裝置,都應已採用 4.4 以上版本的核心。
如要啟用壓縮快照,支援的最低核心版本為 4.19。
將 CONFIG_DM_USER=m
或 CONFIG_DM_USER=y
設為 如果使用前者 (模組),模組必須載入第一階段的 RAM 磁碟。如要達成此目的,請在裝置 Makefile 中加入下列程式行:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Fastboot 工具異動
Android 11 對 fastboot 通訊協定進行了下列變更:
getvar snapshot-update-status
- 傳回開機控制 HAL 傳達給啟動載入程式的值:- 如果狀態為
MERGING
,啟動載入程式必須傳回merging
。 - 如果狀態為
SNAPSHOTTED
,啟動載入程式必須傳回snapshotted
。 - 否則,開機載入程式必須傳回
none
。
- 如果狀態為
snapshot-update merge
:完成合併作業,並視需要啟動至復原/fastbootd。只有在snapshot-update-status
為merging
時,這項指令才有效,且僅支援 fastbootd。snapshot-update cancel
:將開機控制 HAL 的合併狀態設為CANCELLED
。裝置鎖定時,這個指令無效。erase
或wipe
-metadata
、userdata
或保存啟動控制 HAL 合併狀態的分區,應檢查快照合併狀態。erase
wipe
如果狀態為MERGING
或SNAPSHOTTED
,裝置應中止作業。set_active
- 變更有效時段的set_active
指令應檢查快照合併狀態。如果狀態為MERGING
,裝置應中止作業。在SNAPSHOTTED
狀態中,可以安全地變更時段。
這些異動旨在防止裝置意外無法開機,但可能會中斷自動化工具。如果將這些指令當做刷寫所有分區的元件 (例如執行 fastboot flashall
),建議使用下列流程:
- 查詢
getvar snapshot-update-status
。 - 如果是
merging
或snapshotted
,請發出snapshot-update cancel
。 - 繼續執行刷機步驟。
降低儲存空間需求
如果裝置在 super 中未分配完整的 A/B 儲存空間,且預期會視需要使用 /data
,強烈建議使用區塊對應工具。區塊對應工具可確保建構作業之間的區塊分配一致,減少不必要的快照寫入作業。相關說明請參閱「縮減 OTA 大小」。
OTA 壓縮演算法
您可以針對不同的效能指標調整 OTA 封裝。Android 提供多種支援的壓縮方法 (lz4
、zstd
和 none
),這些方法在安裝時間、COW 空間用量、啟動時間和快照合併時間之間有所取捨。啟用壓縮功能的虛擬 AB 測試預設選項為 lz4
compression method
。
微調壓縮
您可以透過兩種方法進一步自訂壓縮演算法:(壓縮層級) (以速度為代價達成的壓縮量) 和 (壓縮係數) (可壓縮的最大視窗大小)。壓縮層級適用於特定演算法 (例如 zstd
),變更層級時,速度和壓縮率會有所取捨。壓縮係數說明 OTA 安裝期間使用的最大壓縮視窗大小。預設值為 64k,但您可以自訂建構參數 PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR
來覆寫預設值。支援的壓縮係數:4k、8k、16k、32k、64k、128k 和 256k。
PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 65536
Pixel 8 Pro 的增量 OTA
不含安裝後階段的安裝時間 | COW 空間用量 | OTA 更新後啟動時間 | 快照合併時間 | |
---|---|---|---|---|
lz4 | 18 分 15 秒 | 2.5 GB | 32.7 秒 | 98.6 秒 |
zstd | 24 分 49 秒 | 2.05 GB | 36.3 秒 | 133.2 秒 |
無 | 16 分 42 秒 | 4.76 GB | 28.7 秒 | 76.6 秒 |
Pixel 8 Pro 的完整 OTA
不含安裝後階段的安裝時間 | COW 空間用量 | OTA 更新後啟動時間 | 快照合併時間 | |
---|---|---|---|---|
lz4 | 15 分 11 秒 | 4.16 GB | 17.6 秒 | 82.2 秒 |
zstd | 16 分 19 秒 | 3.46 GB | 21.0 秒 | 106.3 秒 |
無 | 13 分 33 秒 | 6.39 GB | 18.5 秒 | 92.5 秒 |