縮減 OTA 大小

本頁說明 Android 開放原始碼計畫新增的變更,減少版本之間不必要的檔案變更。 維護自有建構系統的裝置實作人員可將這項資訊做為指引 ,藉此減少無線更新 (OTA) 的大小。

Android OTA 更新偶爾會包含不會對應至程式碼變更的已變更檔案。 實際上就是建構系統構件當同一個程式碼以不同的建構方式建構時,就可能發生這種情況 在不同目錄或不同機器上 都會產生大量變更 檔案。這類超額檔案會增加 OTA 修補程式的大小,且會難以判斷 有哪些變更的程式碼

為了讓 OTA 內容更加透明,Android 開放原始碼計畫納入了 以縮減 OTA 修補程式的大小。版本之間出現不必要的檔案變更 且只有修補程式相關檔案會納入 OTA 更新中。Android 開放原始碼計畫也提供 建構差異比較工具:篩除常見的建構相關 提供更簡潔的建構檔案差異 封鎖對應工具,協助維持封鎖分配 保持一致

建構系統可透過多種方式建立不必要的大型修補程式。為減輕影響, Android 8.0 以上版本導入了新功能,以縮減每個修補程式的大小 檔案差異減少 OTA 更新套件大小的改善項目包括:

  • 使用 ZSTD 這套通用用途、無損壓縮演算法完整處理 A/B 以外裝置更新的映像檔。可自訂 ZSTD,適用於更高層級 藉此增加壓縮率已透過 OTA 設定壓縮等級 並且可以在 --vabc_compression_param=zstd,$COMPRESSION_LEVEL
  • 增加 OTA 中使用的壓縮視窗大小。壓縮時長上限 您可以在裝置 .mk 檔案中自訂建構參數來設定。這個 變數設為 PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
  • 使用 Puffin 重新壓縮這項確定性修補工具 串流,可處理 A/B OTA 更新產生作業的壓縮和差異函式。
  • 差異產生工具使用方式的變更,例如 bsdiff敬上 程式庫用於壓縮修補程式在 Android 9 以上版本中, bsdiff 工具會選擇壓縮演算法 最佳壓縮結果。
  • 改善 update_engine 能減少執行 A/B 裝置更新修補程式時消耗的記憶體。

以下各節討論各種會影響 OTA 更新大小的問題及其解決方案 以及 Android 開放原始碼計畫的實作範例

檔案順序

問題:檔案系統在要求列出清單時,不保證檔案的順序 多個目錄檔案,而同一個結帳頁面通常會是相同的。例如 ls 預設會排序結果,但這類指令使用的萬用字元函式, 因為 findmake 都不會排序。使用這些工具前,您必須先將 這些輸出內容

解決方案:當您使用 findmake 搭配萬用字元函式,請先排序這些指令的輸出內容,再使用 具體做法是指示 Kubernetes 建立並維護 一或多個代表這些 Pod 的物件在以下位置使用 $(wildcard)$(shell find) 時: Android.mk 個檔案,請一併加以排序。有些工具 (例如 Java) 會排序輸入 排序檔案前,請確認目前使用的工具尚未執行。

範例:在核心建構系統中,許多執行個體是使用 內建的 all-*-files-under 巨集,其中包含 all-cpp-files-under (因為數個定義已分散在其他 makefile)。 詳情請參閱下列資源:

建構目錄

問題:變更建構內容的目錄可能會導致 兩者的二進位檔不同Android 建構作業中的大多數路徑都是相對路徑,因此 C/C++ 中的 __FILE__ 不會發生問題。不過,偵錯符號會將 預設路徑名稱,且 .note.gnu.build-id 是從 因此,如果偵錯符號有變動,就會發生變化。

解決方案:Android 開放原始碼計畫現在會建立相對的偵錯路徑。詳情請參閱 CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02

時間戳記

問題:建構輸出內容中的時間戳記會導致不必要的檔案變更。 這很可能會在下列位置發生:

  • C 或 C++ 程式碼中的 __DATE__/__TIME__/__TIMESTAMP__ 巨集。
  • 內嵌於 ZIP 封存檔中的時間戳記。

解決方案/範例:如要從建構輸出內容中移除時間戳記,請使用 操作說明請見 C/C++ 中的__DATE__/__TIME__/__TIMESTAMP__。封存檔中的嵌入時間戳記

C/C++ 中的 __DATE__/__TIME__/__TIMESTAMP__

這些巨集一律會為不同的版本產生不同的輸出內容,因此請勿使用。這裡 下列是幾個不需要這些巨集的選項:

,瞭解如何調查及移除這項存取權。

封存檔案中的嵌入時間戳記 (zip、jar)

Android 7.0 修正了 ZIP 封存檔中嵌入時間戳記的問題, -X 可以全面使用 zip 指令。這移除了 和 ZIP 檔案中的擴充 Unix 時間戳記。

新工具 ziptime (位於 /platform/build/+/main/tools/ziptime/) 會重設 ZIP 標頭中的一般時間戳記。詳情請參閱 README 檔案

signapk 工具會為 APK 檔案設定時間戳記,時間戳記可能會根據 伺服器時區。詳情請參閱 CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028

signapk 工具會為 APK 檔案設定時間戳記,時間戳記可能會根據 伺服器時區。詳情請參閱 CL https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028

版本字串

問題:APK 版本字串通常會加上 BUILD_NUMBER 硬式編碼版本即使 APK 沒有任何其他變更,也導致 APK 則還是不同

解決方案:從 APK 版本字串中移除版本號碼。

這些檢查包括:

啟用裝置端驗證功能

如果為 dm-verity ,接著 OTA 工具會自動選擇您的驗證設定, 啟用裝置端驗證功能這可讓 Android 計算驗證區塊 裝置,而不是在 OTA 套件中儲存為原始位元組。雜訊方塊可以使用 2 GB 分區約為 16 MB

不過,在裝置上運算結果可能需要相當長的時間。具體來說 錯誤修正程式碼可能需要較長的時間才能完成。以 Pixel 裝置來說,大小上限為 10 分鐘。如果是低階裝置,所需時間可能會更長。如果想要停用裝置端驗證 但仍然啟用 dm-verity 的功能 對 ota_from_target_files 工具執行 --disable_fec_computation 權限 再產生 OTA 更新。這個標記會在 OTA 更新期間停用裝置端驗證運算功能。 可縮短 OTA 安裝時間,但增加 OTA 套件大小。如果您的裝置不支援 已啟用 dm-verity,傳送這個標記不會有任何效果。

一致的建構工具

問題:產生已安裝檔案的工具必須一致 (在指定 輸入內容應一律產生相同的輸出內容)。

解決方案/範例:下列建構工具需要進行變更:

使用建構差異比較工具

如果無法消除建構相關檔案變更,Android 開放原始碼計畫會納入 建構差異比較工具 target_files_diff.py 以便用於比較兩個檔案套件這個工具會對兩個指標執行遞迴差異 建構作業,但不包括常見的建構相關檔案變更

  • 預期的建構輸出內容變更 (例如因版本編號變更)。
  • 因目前建構系統的已知問題而所做的變更。

如要使用建構差異比較工具,請執行下列指令:

target_files_diff.py dir1 dir2

dir1dir2 是包含所擷取目標的基本目錄 適用於個別版本的檔案

保持區塊分配一致

對特定檔案而言,雖然其內容在兩個版本之間保持不變,但實際區塊 暫存資料可能有所變更因此,更新程式必須執行不必要的 I/O 來移動 OTA 更新區塊。

在虛擬 A/B OTA 更新中,不必要的 I/O 可能會大幅增加所需的儲存空間 儲存寫入複製快照的快照。在非 A/B OTA 更新中, OTA 更新會縮短更新時間,讓更多 I/O 作業因排程移動而增加。

為解決這個問題,在 Android 7.0 中,Google 擴充了 make_ext4fs 工具: 確保不同版本之間的區塊配置保持一致make_ext4fs 工具接受 選用的 -d base_fs 旗標,會嘗試將檔案分配至相同區塊 生成 ext4 圖片您可以將區塊對應檔 (例如 base_fs 對應檔案)ZIP 檔案,對於每項 ext4 分區,有 .map 檔案位於 IMAGES 目錄 (例如 IMAGES/system.map 對應到 system 分區)。這 base_fs 個檔案可供簽到 是透過 PRODUCT_<partition>_BASE_FS_PATH 來指定,如以下範例所示:

  PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map
  PRODUCT_SYSTEM_EXT_BASE_FS_PATH := path/to/base_fs_files/base_system_ext.map
  PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map
  PRODUCT_PRODUCT_BASE_FS_PATH := path/to/base_fs_files/base_product.map
  PRODUCT_ODM_BASE_FS_PATH := path/to/base_fs_files/base_odm.map

雖然這麼做無法縮減整體 OTA 套件大小,但確實能改善 OTA 更新 藉此降低 I/O 效能虛擬 A/B 更新大幅降低 套用 OTA 所需的儲存空間容量

避免更新應用程式

除了盡量減少建構差異外,您還可以排除更新,藉此縮減 OTA 更新大小 可讓你透過應用程式商店更新應用程式APK 通常屬於 裝置上有多個分區包含可透過應用程式更新的最新版應用程式 可能會大幅影響 OTA 套件的規格,而且只會對少量使用者造成太大影響 好處。當使用者收到 OTA 套件時,他們可能已經已安裝新版應用程式,或 也就是直接從應用程式商店取得