Google致力於提高黑人社區的種族平等。 怎麼看。
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

實施A / B更新

想要實現A / B系統更新的OEM和SoC供應商必須確保其引導加載程序實現boot_control HAL並將正確的參數傳遞給內核。

實施啟動控制HAL

具有A / B功能的引導程序必須在hardware/libhardware/include/hardware/boot_control.h處實現boot_control HAL。您可以使用system/extras/bootctl實用程序和system/extras/tests/bootloader/來測試實現。

您還必須實現如下所示的狀態機:

圖1. Bootloader狀態機

設置內核

要實施A / B系統更新:

  1. Cherrypick以下內核補丁系列(如果需要):
  2. 確保內核命令行參數包含以下額外參數:
    skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>" 
    ...,其中<public-key-id>值是用於驗證真實性表簽名的公共密鑰的ID(有關詳細信息,請參閱dm-verity )。
  3. 將包含公鑰的.X509證書添加到系統密鑰環中:
    1. 將以.der格式格式化的.X509證書複製到kernel目錄的根目錄中。如果.X509證書的格式設置為.pem文件,請使用以下openssl命令將.pem格式轉換為.der格式:
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. 構建zImage以將證書包括在系統密鑰環中。要進行驗證,請檢查procfs條目(要求啟用KEYS_CONFIG_DEBUG_PROC_KEYS ):
      angler:/# cat /proc/keys
      
      1c8a217e I------     1 perm 1f010000     0     0 asymmetri
      Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
      2d454e3e I------     1 perm 1f030000     0     0 keyring
      .system_keyring: 1/4
      成功包含.X509證書表示系統密鑰環中存在公共密鑰(突出顯示表示公共密鑰ID)。
    3. #替換空格,然後在內核命令行中將其作為<public-key-id>傳遞。例如,傳遞Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f代替<public-key-id>

設置構建變量

具有A / B功能的引導加載程序必須滿足以下構建變量條件:

必須定義A / B目標
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
    boot \
    system \
    vendor
    以及通過update_engine更新的其他分區(無線電,引導加載程序等)
  • PRODUCT_PACKAGES += \
    update_engine \
    update_verifier
有關示例,請參閱/device/google/marlin/+/android-7.1.0_r1/device-common.mk 。您可以選擇執行Compiling中所述的安裝後(但需要重新引導)dex2oat步驟。
強烈推薦用於A / B目標
  • 定義TARGET_NO_RECOVERY := true
  • 定義BOARD_USES_RECOVERY_AS_BOOT := true
  • 不定義BOARD_RECOVERYIMAGE_PARTITION_SIZE
無法定義A / B目標
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
調試版本可選 PRODUCT_PACKAGES_DEBUG += update_engine_client

設置分區(插槽)

A / B設備不需要恢復分區或緩存分區,因為Android不再使用這些分區。現在,數據分區用於下載的OTA軟件包,並且恢復映像代碼位於引導分區上。是A / B-ED應如下命名的所有分區(時隙總是被命名為ab ,等): boot_aboot_bsystem_asystem_bvendor_avendor_b

快取

對於非A / B更新,緩存分區用於存儲下載的OTA軟件包,並在應用更新時臨時存儲塊。從來沒有一種很好的方法來調整緩存分區的大小:需要多少取決於您要應用的更新。最壞的情況是與系統映像一樣大的緩存分區。使用A / B更新,不需要存儲塊(因為您一直在寫入當前未使用的分區),而使用流A / B,則無需在應用之前下載整個OTA軟件包。

復甦

恢復RAM磁盤現在包含在boot.img文件中。進行恢復時,引導加載程序無法skip_initramfs選項放在內核命令行上。

對於非A / B更新,恢復分區包含用於應用更新的代碼。 A / B更新由運行在常規引導系統映像中的update_engine應用。仍然有一種恢復模式用於實現工廠數據重置和更新包的側面加載(這是“恢復”的名稱)。恢復模式的代碼和數據存儲在ramdisk的常規引導分區中。要引導進入系統映像,引導程序會告訴內核跳過ramdisk(否則設備將引導至恢復模式。恢復模式很小(並且大部分已經在引導分區上了),因此引導分區不會增加在尺寸方面。

Fstab

slotselect參數必須在A / B分區的行上。例如:

<path-to-block-device>/vendor  /vendor  ext4  ro
wait,verify=<path-to-block-device>/metadata,slotselect

不應將任何分區命名為vendor 。相反,將選擇分區vendor_avendor_b並將其安裝在/vendor掛載點上。

內核插槽參數

當前的插槽後綴應通過特定的設備樹(DT)節點( /firmware/android/slot_suffix )或通過androidboot.slot_suffix命令行參數androidboot.slot_suffix

默認情況下,fastboot會刷新A / B設備上的當前插槽。如果更新程序包還包含其他非當前插槽的映像,則fastboot也會刷新這些映像。可用的選項包括:

  • --slot SLOT 。覆蓋默認行為,並提示fastboot刷新作為參數傳入的插槽。
  • --set-active [ SLOT ] 。將插槽設置為活動狀態。如果未指定任何可選參數,則將當前插槽設置為活動狀態。
  • fastboot --help 。獲取有關命令的詳細信息。

如果引導加載程序實現了快速引導,則它應支持將當前活動插槽設置為給定插槽的命令set_active <slot> (這還必須清除該插槽的不可引導標誌並將重試計數重置為默認值)。引導加載程序還應該支持以下變量:

  • has-slot:<partition-base-name-without-suffix> 。如果給定分區支持插槽,則返回“是”,否則返回“否”。
  • current-slot 。返回將從下一個引導的插槽後綴。
  • slot-count 。返回表示可用插槽數的整數。當前,支持兩個插槽,因此該值為2
  • slot-successful:<slot-suffix> 。如果給定的插槽已標記為成功引導,則返回“是”,否則返回“否”。
  • slot-unbootable:<slot-suffix> 。如果給定的插槽被標記為不可引導,則返回“是”,否則返回“否”。
  • slot-retry-count 。嘗試引導給定插槽的剩餘重試次數。

要查看所有變量,請運行fastboot getvar all

生成OTA軟件包

OTA軟件包工具遵循與非A / B設備相同的命令。必須通過定義A / B目標的構建變量來生成target_files.zip文件。 OTA軟件包工具會以A / B更新程序的格式自動識別並生成軟件包。

例子:

  • 生成完整的OTA:
    ./build/make/tools/releasetools/ota_from_target_files \
        dist_output/tardis-target_files.zip \
        ota_update.zip
    
  • 生成增量OTA:
    ./build/make/tools/releasetools/ota_from_target_files \
        -i PREVIOUS-tardis-target_files.zip \
        dist_output/tardis-target_files.zip \
        incremental_ota_update.zip
    

配置分區

update_engine可以更新同一磁盤中定義的任意一對A / B分區。一對分區具有公共前綴(例如systemboot )和每個插槽的後綴(例如_a )。有效負載生成器為其定義更新的分區列表由AB_OTA_PARTITIONS make變量配置。

例如,如果包含一對分區bootloader_abooloader_b_a_b是插槽後綴),則可以通過在產品或主板配置上指定以下內容來更新這些分區:

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

update_engine更新的所有分區都不能被系統的其餘部分修改。在增量或增量更新期間,當前插槽中的二進制數據將用於在新插槽中生成數據。任何修改都可能導致新插槽數據在更新過程中無法通過驗證,從而使更新失敗。

配置安裝後

您可以使用一組鍵值對為每個更新的分區以不同的方式配置安裝後步驟。要在新映像中運行位於/system/usr/bin/postinst的程序,請指定相對於系統分區中文件系統根目錄的路徑。

例如, usr/bin/postinstsystem/usr/bin/postinst (如果不使用RAM磁盤)。另外,指定文件系統類型以傳遞給mount(2)系統調用。將以下內容添加到產品或設備.mk文件中(如果適用):

AB_OTA_POSTINSTALL_CONFIG += \
  RUN_POSTINSTALL_system=true \
  POSTINSTALL_PATH_system=usr/bin/postinst \
  FILESYSTEM_TYPE_system=ext4

編譯中

出於安全原因, system_server無法使用即時(JIT)編譯。這意味著您必須至少為system_server及其依賴項提前編譯odex文件。其他都是可選的。

要在後台編譯應用,您必須在產品的設備配置(在產品的device.mk中)中添加以下內容:

  1. 在構建中包括本機組件,以確保編譯編譯腳本和二進製文件並將其包含在系統映像中。
      # A/B OTA dexopt package
      PRODUCT_PACKAGES += otapreopt_script
    
  2. 將編譯腳本連接到update_engine ,以便在安裝後步驟中運行。
      # A/B OTA dexopt update_engine hookup
      AB_OTA_POSTINSTALL_CONFIG += \
        RUN_POSTINSTALL_system=true \
        POSTINSTALL_PATH_system=system/bin/otapreopt_script \
        FILESYSTEM_TYPE_system=ext4 \
        POSTINSTALL_OPTIONAL_system=true
    

有關在未使用的第二個系統分區中安裝首選文件的幫助,請參閱DEX_PREOPT文件的首次啟動安裝