Уменьшить размер OTA

На этой странице описываются изменения, добавленные в AOSP для сокращения ненужных изменений файлов между сборками. Разработчики устройств, которые поддерживают собственные системы сборки, могут использовать эту информацию в качестве руководства по уменьшению размера своих обновлений по воздуху (OTA).

Обновления Android OTA иногда содержат измененные файлы, которые не соответствуют изменениям кода. На самом деле это артефакты системы сборки. Это может произойти, когда один и тот же код, собранный в разное время, из разных каталогов или на разных машинах, создает большое количество измененных файлов. Такие избыточные файлы увеличивают размер исправления OTA и затрудняют определение того, какой код изменился.

Чтобы сделать содержимое OTA более прозрачным, AOSP включает изменения системы сборки, разработанные для уменьшения размера исправлений OTA. Ненужные изменения файлов между сборками были устранены, и только файлы, связанные с исправлениями, содержатся в обновлениях OTA. AOSP также включает инструмент сравнения сборок , который отфильтровывает общие изменения файлов, связанных со сборкой, чтобы обеспечить более чистый файл сравнения сборок, и инструмент сопоставления блоков , который помогает вам поддерживать единообразное распределение блоков.

Система сборки может создавать ненужно большие патчи несколькими способами. Чтобы смягчить это, в Android 8.0 и выше были реализованы новые функции, позволяющие уменьшить размер патча для каждого файла diff. Улучшения, которые уменьшили размеры пакетов OTA-обновлений, включают следующее:

  • Использование ZSTD , универсального алгоритма сжатия без потерь для полных изображений при обновлениях устройств не-A/B. ZSTD можно настроить для более высоких коэффициентов сжатия, увеличив уровень сжатия. Уровень сжатия устанавливается во время генерации OTA и может быть установлен путем передачи флага --vabc_compression_param=zstd,$COMPRESSION_LEVEL
  • Увеличение размера окна сжатия, используемого во время OTA. Максимальный размер окна сжатия можно задать, настроив параметр сборки в файле .mk устройства. Эта переменная задается как PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
  • Использование рекомпрессии Puffin , детерминированного инструмента исправления для потоков Deflate, который обрабатывает функции сжатия и сравнения для генерации обновлений A/B OTA.
  • Изменения в использовании инструмента дельта-генерации, например, как библиотека bsdiff используется для сжатия патчей. В Android 9 и выше инструмент bsdiff выбирает алгоритм сжатия, который даст наилучшие результаты сжатия для патча.
  • Улучшения в update_engine привели к уменьшению потребления памяти при применении исправлений для обновлений устройств A/B.

В следующих разделах обсуждаются различные проблемы, влияющие на размеры OTA-обновлений, их решения и примеры реализации в AOSP.

Порядок файлов

Проблема : Файловые системы не гарантируют порядок файлов при запросе списка файлов в каталоге, хотя он обычно одинаков для одного и того же извлечения. Такие инструменты, как ls сортируют результаты по умолчанию, но функция подстановочных знаков, используемая такими командами, как find и make , не сортирует. Перед использованием этих инструментов необходимо отсортировать выходные данные.

Решение : При использовании таких инструментов, как find и make с функцией wildcard, отсортируйте вывод этих команд перед их использованием. При использовании $(wildcard) или $(shell find) в файлах Android.mk также отсортируйте их. Некоторые инструменты, такие как Java, сортируют входные данные, поэтому перед сортировкой файлов убедитесь, что используемый вами инструмент еще не сделал этого.

Примеры: Многие экземпляры были исправлены в основной системе сборки с использованием встроенного макроса all-*-files-under , который включает all-cpp-files-under (так как несколько определений были разбросаны по другим файлам makefile). Подробности см. в следующем:

Каталог сборки

Проблема: Изменение каталога, в котором все собрано, может привести к тому, что двоичные файлы будут отличаться. Большинство путей в сборке Android являются относительными, поэтому __FILE__ в C/C++ не является проблемой. Однако отладочные символы кодируют полное имя пути по умолчанию, а .note.gnu.build-id генерируется путем хеширования предварительно очищенного двоичного файла, поэтому он изменится, если изменятся отладочные символы.

Решение: AOSP теперь делает пути отладки относительными. Подробности см. в CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02 .

Временные метки

Проблема: Временные метки в выходных данных сборки приводят к ненужным изменениям файлов. Это может произойти в следующих местах:

  • Макросы __DATE__/__TIME__/__TIMESTAMP__ в коде C или C++.
  • Временные метки, встроенные в zip-архивы.

Решения/Примеры: Чтобы удалить временные метки из выходных данных сборки, используйте инструкции, приведенные ниже в разделах __DATE__/__TIME__/__TIMESTAMP__ в C/C++ и Встроенные временные метки в архивах .

__ДАТА__/__ВРЕМЯ__/__МЕТКА__ в C/C++

Эти макросы всегда производят разные результаты для разных сборок, поэтому не используйте их. Вот несколько вариантов устранения этих макросов:

Встроенные временные метки в архивах (zip, jar)

Android 7.0 исправил проблему встроенных временных меток в zip-архивах, добавив -X ко всем использованиям команды zip . Это удалило UID/GID строителя и расширенную временную метку Unix из zip-файла.

Новый инструмент ziptime (расположен в /platform/build/+/android16-release/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 автоматически подхватывают вашу конфигурацию verity и включают вычисление verity на устройстве. Это позволяет вычислять блоки verity на устройствах Android, а не хранить их в виде сырых байтов в вашем пакете OTA. Блоки verity могут использовать примерно 16 МБ для раздела размером 2 ГБ.

Однако вычисление verity на устройстве может занять много времени. В частности, код Forward Error-correction может занять много времени. На пиксельных устройствах это обычно занимает до 10 минут. На бюджетных устройствах это может занять больше времени. Если вы хотите отключить вычисление verity на устройстве, но при этом включить dm-verity, вы можете сделать это, передав --disable_fec_computation инструменту ota_from_target_files при создании обновления OTA. Этот флаг отключает вычисление verity на устройстве во время обновлений OTA. Он сокращает время установки OTA, но увеличивает размер пакета OTA. Если на вашем устройстве не включен dm-verity, передача этого флага не имеет никакого эффекта.

Последовательные инструменты сборки

Проблема: Инструменты, генерирующие установленные файлы, должны быть единообразными (данные входные данные всегда должны давать одинаковый результат).

Решения/Примеры: Изменения потребовались в следующих инструментах сборки:

Используйте инструмент сравнения сборок

Для случаев, когда невозможно исключить изменения файлов, связанные со сборкой, AOSP включает инструмент сравнения сборок target_files_diff.py для использования при сравнении двух пакетов файлов. Этот инструмент выполняет рекурсивное сравнение двух сборок, исключая общие изменения файлов, связанные со сборкой, такие как

  • Ожидаемые изменения в результатах сборки (например, из-за изменения номера сборки).
  • Изменения вызваны известными проблемами в текущей системе сборки.

Чтобы использовать инструмент сравнения сборок, выполните следующую команду:

target_files_diff.py dir1 dir2

dir1 и dir2 — это базовые каталоги, содержащие извлеченные целевые файлы для каждой сборки.

Поддерживайте единообразие распределения блоков

Для данного файла, хотя его содержимое остается неизменным между двумя сборками, фактические блоки, содержащие данные, могли измениться. В результате, обновитель должен выполнять ненужные операции ввода-вывода, чтобы перемещать блоки для обновления OTA.

В виртуальном обновлении A/B OTA ненужные операции ввода-вывода могут значительно увеличить объем хранилища, необходимый для хранения моментального снимка копирования при записи. В не-A/B OTA-обновлении перемещение блоков для обновления OTA увеличивает время обновления, поскольку из-за перемещения блоков происходит больше операций ввода-вывода.

Чтобы решить эту проблему, в 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 за счет сокращения количества операций ввода-вывода. Для обновлений Virtual A/B это радикально уменьшает объем дискового пространства, необходимого для применения OTA.

Избегайте обновления приложений

Помимо минимизации различий в сборках, вы можете уменьшить размеры обновлений OTA, исключив обновления для приложений, которые получают обновления через магазины приложений. APK часто составляют значительную часть различных разделов на устройстве. Включение последних версий приложений, которые обновляются магазинами приложений, в обновление OTA может оказать большое влияние на размер пакетов OTA и предоставить мало преимуществ для пользователей. К тому времени, как пользователи получат пакет OTA, они уже могут иметь обновленное приложение или даже более новую версию, полученную напрямую из магазинов приложений.