Внедрение обновлений A / B

OEM - производители и SoC поставщиков , которые хотят реализовать A / B обновление системы должно гарантировать , что их загрузчик реализует boot_control HAL и передают правильные параметры ядру.

Реализация HAL управления загрузкой

A / B-способные загрузчики должны реализовывать boot_control HAL на hardware/libhardware/include/hardware/boot_control.h в hardware/libhardware/include/hardware/boot_control.h и hardware/libhardware/include/hardware/boot_control.h или hardware/libhardware/include/hardware/boot_control.h . Вы можете проверить реализации с помощью system/extras/bootctl полезности и system/extras/tests/bootloader/ .

Вы также должны реализовать конечный автомат, показанный ниже:

Состояние машины Рисунок 1. Загрузчик

Настройка ядра

Чтобы внедрить обновления системы 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> значение является идентификатором открытого ключа , используемым для проверки правдивости таблицы подписи (подробнее см ой правдивости ) .
  3. Добавьте сертификат .X509, содержащий открытый ключ, в системную связку ключей:
    1. Скопируйте .X509 сертификат , отформатированный в .der формате в корне 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 указывает на наличие открытого ключа в системе брелока (изюминка обозначает идентификатор ключа общественности).
    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 . При желании можно провести после установки (но предварительно перезагрузиться) 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-е изд должен быть назван следующим образом (слоты всегда называются , a b и т.д.): boot_a , boot_b , system_a , system_b , vendor_a , vendor_b .

Кеш

Для обновлений, отличных от A / B, раздел кеша использовался для хранения загруженных пакетов OTA и для временного хранения блоков при применении обновлений. Никогда не было хорошего способа изменить размер раздела кеша: насколько он должен быть большим, зависело от того, какие обновления вы хотите применить. В худшем случае размер раздела кэша равен размеру образа системы. С обновлениями A / B нет необходимости хранить блоки (потому что вы всегда записываете в раздел, который в настоящее время не используется), а с потоковой передачей A / B нет необходимости загружать весь пакет OTA перед его применением.

Восстановление

Восстановление RAM диск теперь содержится в boot.img файле. При переходе на восстановление, загрузчик не может поставить skip_initramfs параметра в командной строке ядра.

Для обновлений, отличных от A / B, раздел восстановления содержит код, используемый для применения обновлений. A Обновление / B применяется update_engine работает в обычном Booted изображения системы. По-прежнему существует режим восстановления, используемый для сброса заводских данных и загрузки неопубликованных пакетов обновлений (отсюда и произошло название «восстановление»). Код и данные для режима восстановления хранятся в обычном загрузочном разделе на ramdisk; для загрузки в образ системы загрузчик сообщает ядру пропустить ramdisk (в противном случае устройство загружается в режим восстановления. Режим восстановления небольшой (и большая часть его уже была в загрузочном разделе), поэтому загрузочный раздел не увеличивается по размеру.

Fstab

slotselect аргумент должен быть на линии для разделов A / B-е изд. Например:

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

Нет раздела не должен быть назван vendor . Вместо этого раздела vendor_a или vendor_b будет выбрано и смонтировано на /vendor точки монтирования.

Аргументы слота ядра

Тока суффикс слот должен быть передан либо через конкретное устройство дерева (ДТ) узла ( /firmware/android/slot_suffix ) или через androidboot.slot_suffix командной строки или bootconfig аргумента ядра.

По умолчанию fastboot мигает текущий слот на устройстве A / B. Если пакет обновления также содержит образы для другого, не текущего слота, fastboot также мигает эти образы. Доступные варианты включают:

  • --slot SLOT . Отмените поведение по умолчанию и предложите fastboot прошить слот, переданный в качестве аргумента.
  • --set-active [ SLOT ] . Установите слот как активный. Если необязательный аргумент не указан, текущий слот устанавливается как активный.
  • fastboot --help . Получите подробную информацию о командах.

Если FastBoot загрузчика инвентарь, он должен поддерживать команду 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 инструментов пакета следует той же команде, что и команды для не-А / В устройствах. target_files.zip файл должен быть создан путем определения переменной сборки для мишени A / B. Инструменты пакета 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 может обновить любую пару разделов А / В , определенных в том же самом диске. Пара перегородок имеет общий префикс (например, system или boot ) и каждый интервал времени суффикса (например, _a ). Список разделов , для которых генератор полезной нагрузки определяет обновление настраивается с помощью AB_OTA_PARTITIONS сделать переменную.

Например, если пара разделов bootloader_a и booloader_b включены ( _a и _b являются игровыми суффиксами), вы можете обновить эти разделы, указав следующее по конфигурации продукта или платы:

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

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

Настройка после установки

Вы можете настроить этап после установки по-разному для каждого обновленного раздела, используя набор пар ключ-значение. Чтобы запустить программу , расположенную в /system/usr/bin/postinst в новом образе, указать путь относительно корня файловой системы в системном разделе.

Например, usr/bin/postinst является system/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 и его зависимостей, как минимум; все остальное необязательно.

Чтобы компилировать приложения в фоновом режиме, вы должны добавить следующее в конфигурацию устройства продукта (в файле 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
    

Для получения справки по установке в preopted файлов в неиспользуемом втором разделе системы, обратитесь к первой загрузке установке DEX_PREOPT файлов .