實現虛擬 A/B

要在新設備上實施虛擬 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必須大於或等於總和(更新組的大小)+開銷,這又必須大於或等於總和(分區的大小)+開銷

要使用虛擬 A/B 啟用壓縮快照,請改為繼承以下基本配置:

$(call inherit-product, \
    $(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)

引導控制 HAL

引導控制HAL提供OTA客戶控制的引導槽的接口。虛擬 A/B 需要對引導控制 HAL 進行次要版本升級,因為需要額外的 API 來確保引導加載程序在刷新/恢復出廠設置期間受到保護。見IBootControl.haltypes.hal的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_SNAPSHOTtrue

對於使用F2FS設備,包括f2fs:出口FS_NOCOW_FL標誌,以用戶的內核補丁來修復文件牽制。包括f2fs:支持對準固定文件內核補丁也是如此。

虛擬A / B依賴於內核版本4.3新增功能:在溢出狀態位snapshotsnapshot-merge目標。所有搭載 Android 9 及更高版本的設備都應該已經擁有 4.4 或更高版本的內核。

要啟用壓縮快照,支持的最低內核版本為 4.19。集CONFIG_DM_USER=mCONFIG_DM_USER=y 。如果使用前者(一個模塊),則該模塊必須加載到第一階段的 ramdisk 中。這可以通過在設備 Makefile 中添加以下行來實現:

BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko

在升級到 Android 11 的設備上進行改造

升級到 Android 11 時,使用動態分區啟動的設備可以選擇改造虛擬 A/B。更新過程與使用虛擬 A/B 啟動的設備大致相同,但有一些細微差別:

  • 的COW文件的位置-對於發射裝置中,OTA客戶端使用的超級分區中所有可用的空空間,使用空間前/data 。對於改裝設備,總有在超級分區,以便將COW文件是永遠不會上創建足夠的空間/data

  • 構建時功能標誌-對於改裝虛擬A / B設備,既PRODUCT_VIRTUAL_AB_OTAPRODUCT_VIRTUAL_AB_OTA_RETROFIT被設置為true ,如下圖所示:

    (call inherit-product, \
        (SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
    
  • 中超分區大小-設備與虛擬的發射/ B可以減少BOARD_SUPER_PARTITION_SIZE了一半,因為B插槽不在超級分區。設備改造虛擬A / B保持舊超級分區的大小,所以BOARD_SUPER_PARTITION_SIZE是大於或等於2 *總和(更新組的大小)+開銷,而這又是大於或等於2 *總和(分區的大小) +開銷

引導加載程序更改

更新期間的合併步驟/data保存的是Android OS唯一的整個實例。一旦遷移開始,原生systemvendorproduct分區是不完整的,直到複製完成。如果設備在此過程中通過恢復或通過系統設置對話框恢復出廠設置,則設備將無法啟動。

擦除前/data ,完成合併在根據設備狀態恢復或回滾:

  • 如果新構建之前成功啟動,請完成遷移。
  • 否則,回滾到舊插槽:
    • 對於動態分區,回滾到之前的狀態。
    • 對於靜態分區,將活動插槽設置為舊插槽。

兩個引導加載程序和fastbootd能夠擦除/data如果該設備被解鎖分區。雖然fastbootd可以強制完成遷移,引導程序不能。引導加載程序不知道合併是否是在進步,還是什麼塊/data構成了操作系統的分區。設備必須通過執行以下操作來防止用戶在不知不覺中使設備無法操作(變磚):

  1. 實現引導控制HAL使得引導程序可讀取由所述值集合setSnapshotMergeStatus()方法。
  2. 如果合併狀態MERGING ,或者如果合併狀態SNAPSHOTTED和插槽已更改為新更新的插槽中,然後請求擦userdatametadata ,或分區存儲合併狀態必須在引導程序被拒絕。
  3. 實施fastboot snapshot-update cancel命令,使用戶可以發出信號,告知他們要繞過這個保護機制的引導程序。
  4. 修改自定義閃存工具或腳本問題fastboot snapshot-update cancel閃光整個設備時。這是安全的,因為刷新整個設備會刪除 OTA。工具可以通過實現在運行時檢測到這種命令fastboot getvar snapshot-update-status 。此命令有助於區分錯誤條件。

例子

struct VirtualAbState {
    uint8_t StructVersion;
    uint8_t MergeStatus;
    uint8_t SourceSlot;
};

bool ShouldPreventUserdataWipe() {
    VirtualAbState state;
    if (!ReadVirtualAbState(&state)) ...
    return state.MergeStatus == MergeStatus::MERGING ||
           (state.MergeStatus == MergeStatus::SNAPSHOTTED &&
            state.SourceSlot != CurrentSlot()));
}

Fastboot 工具更改

Android 11 對 fastboot 協議進行了以下更改:

  • getvar snapshot-update-status -返回值的引導控制HAL傳達到bootloader:
    • 如果狀態MERGING ,引導程序必須返回merging
    • 如果狀態SNAPSHOTTED ,引導程序必須返回snapshotted
    • 否則,引導加載程序必須返回none
  • snapshot-update merge -完成合併操作,如果有必要引導到恢復/ fastbootd。此命令只如果snapshot-update-status進行merging ,並且只在fastbootd支持。
  • snapshot-update cancel -設置引導控制HAL的合併狀態CANCELLED 。該命令在設備鎖定時無效。
  • erasewipe -一個erasewipemetadatauserdata ,或分區持有引導控制HAL應檢查快照合併狀態合併狀態。如果狀態MERGINGSNAPSHOTTED ,該設備應中止操作。
  • set_active -一個set_active命令更改活動插槽應檢查快照合併狀態。如果狀態MERGING ,設備應中止操作。該插槽可以安全地在改變SNAPSHOTTED狀態。

這些更改旨在防止意外使設備無法啟動,但它們可能會破壞自動化工具。當命令被用作閃爍所有分區,如運行的組件fastboot flashall ,建議使用以下流程:

  1. 查詢getvar snapshot-update-status
  2. 如果mergingsnapshotted ,問題snapshot-update cancel
  3. 繼續閃爍的步驟。

減少存儲需求

沒有設備在超分配的全A / B的存儲,並希望使用/data在必要時,我們強烈建議使用塊映射工具。塊映射工具在構建之間保持塊分配一致,減少對快照的不必要寫入。這是記錄下減少OTA大小