Чтобы реализовать виртуальный 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 больше не находятся в режиме super. То есть BOARD_SUPER_PARTITION_SIZE
должен быть больше или равен сумме (размеру групп обновлений) + накладные расходы , которые, в свою очередь, должны быть больше или равны сумме (размеру разделов) + накладные расходы .
Для Android 13 и более поздних версий, чтобы включить сжатие снимков с помощью Virtual A/B, унаследуйте следующую базовую конфигурацию:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)
Это позволяет создавать снимки пользовательского пространства с помощью Virtual A/B при использовании метода безоперационного сжатия. Затем вы можете настроить метод сжатия на один из поддерживаемых методов: gz
, zstd
и lz4
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
В Android 12, чтобы включить сжатые снимки с помощью Virtual A/B, унаследуйте следующую базовую конфигурацию:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
XOR-сжатие
На устройствах, обновляющихся до Android 13 и более поздних версий, функция сжатия XOR не включена по умолчанию. Чтобы включить сжатие XOR, добавьте следующее в файл .mk
устройства.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
Сжатие XOR включено по умолчанию для устройств, наследуемых от android_t_baseline.mk
.
Объединение пользовательского пространства
Для устройств, обновляющихся до Android 13 и более поздних версий, процесс слияния пользовательского пространства, как описано в разделе «Наложение слоев устройства сопоставления устройств», по умолчанию не включен. Чтобы включить объединение пользовательского пространства, добавьте следующую строку в файл .mk
устройства:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
Объединение пользовательского пространства включено по умолчанию на устройствах, запускаемых с версией 13 и выше.
Управление загрузкой HAL
HAL управления загрузкой предоставляет OTA-клиентам интерфейс для управления загрузочными слотами. Virtual A/B требует незначительного обновления версии HAL управления загрузкой, поскольку необходимы дополнительные API-интерфейсы для обеспечения защиты загрузчика во время прошивки или сброса настроек. См. IBootControl.hal и Types.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_SNAPSHOT
значение true
.
Для устройств, использующих F2FS, включите флаг f2fs:export FS_NOCOW_FL в пользовательское исправление ядра, чтобы исправить закрепление файлов. Включите также патч ядра f2fs: support выровненных закрепленных файлов .
Virtual A/B опирается на функции, добавленные в версии ядра 4.3: бит состояния переполнения в целях snapshot
и snapshot-merge
. Все устройства, запускаемые с Android 9 и более поздних версий, уже должны иметь ядро версии 4.4 или более поздней версии.
Чтобы включить сжатые снимки, минимальная поддерживаемая версия ядра — 4.19. Установите CONFIG_DM_USER=m
или CONFIG_DM_USER=y
. При использовании первого (модуля) модуль должен быть загружен на виртуальный диск первого этапа. Этого можно добиться, добавив в 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_OTA
иPRODUCT_VIRTUAL_AB_OTA_RETROFIT
имеют значениеtrue
, как показано ниже:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Размер суперраздела . Устройства, запускаемые с виртуальным A/B, могут сократить
BOARD_SUPER_PARTITION_SIZE
вдвое, поскольку слоты B отсутствуют в суперразделе. Устройства, модернизирующие виртуальный A/B, сохраняют старый размер суперраздела, поэтомуBOARD_SUPER_PARTITION_SIZE
больше или равно 2 * sum(размер групп обновлений) + накладные расходы , которые, в свою очередь, больше или равны 2 * sum(размер разделов). + накладные расходы .
Изменения загрузчика
На этапе слияния обновления /data
содержит единственный целый экземпляр ОС Android. После начала миграции разделы собственной system
, vendor
и product
остаются неполными до завершения копирования. Если во время этого процесса устройство будет сброшено до заводских настроек либо путем восстановления, либо через диалоговое окно настроек системы, устройство будет невозможно загрузить.
Прежде чем стирать /data
, завершите слияние в режиме восстановления или отката в зависимости от состояния устройства:
- Если новая сборка ранее успешно загружалась, завершите миграцию.
- В противном случае откат к старому слоту:
- Для динамических разделов выполните откат к предыдущему состоянию.
- Для статических разделов установите активный слот на старый слот.
И загрузчик, и fastbootd
могут стереть раздел /data
, если устройство разблокировано. Хотя fastbootd
может принудительно завершить миграцию, загрузчик не может. Загрузчик не знает, происходит ли слияние или какие блоки в /data
составляют разделы ОС. Устройства должны препятствовать тому, чтобы пользователь по незнанию вывел устройство из строя (блокировал его), выполнив следующие действия:
- Реализуйте HAL управления загрузкой, чтобы загрузчик мог прочитать значение, установленное методом
setSnapshotMergeStatus()
. - Если статус слияния —
MERGING
или если статус слияния —SNAPSHOTTED
и слот изменился на недавно обновленный слот, то запросы на стираниеuserdata
,metadata
или раздела, хранящего статус слияния, должны быть отклонены в загрузчике. - Реализуйте команду
fastboot snapshot-update cancel
, чтобы пользователи могли сигнализировать загрузчику, что они хотят обойти этот механизм защиты. - Измените специальные инструменты или сценарии прошивки, чтобы они выдавали
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()));
}
Изменения в инструментах быстрой загрузки
Android 11 вносит следующие изменения в протокол быстрой загрузки:
-
getvar snapshot-update-status
— Возвращает значение, которое HAL управления загрузкой сообщил загрузчику:- Если состояние
MERGING
, загрузчик должен вернутьmerging
. - Если состояние
SNAPSHOTTED
, загрузчик должен вернутьsnapshotted
. - В противном случае загрузчик должен вернуть
none
.
- Если состояние
-
snapshot-update merge
— завершает операцию слияния, загружаясь при необходимости в Recovery/fastbootd. Эта команда действительна только в том случае, еслиsnapshot-update-status
—merging
, и поддерживается только в fastbootd. -
snapshot-update cancel
— устанавливает статус слияния HAL элемента управления загрузкой вCANCELLED
. Эта команда недействительна, когда устройство заблокировано. -
erase
илиwipe
—erase
илиwipe
metadata
,userdata
или раздела, содержащего статус слияния для HAL управления загрузкой, должен проверять статус слияния моментальных снимков. Если статусMERGING
илиSNAPSHOTTED
, устройство должно прервать операцию. -
set_active
— командаset_active
, изменяющая активный слот, должна проверять статус слияния моментальных снимков. Если статусMERGING
, устройство должно прервать операцию. Слот можно безопасно изменить в состоянииSNAPSHOTTED
.
Эти изменения призваны предотвратить случайную невозможность загрузки устройства, но они могут помешать работе автоматизированных инструментов. Когда команды используются как компонент прошивки всех разделов, например, при запуске fastboot flashall
, рекомендуется использовать следующий порядок действий:
- Запросите
getvar snapshot-update-status
. - В случае
merging
илиsnapshotted
выполните командуsnapshot-update cancel
. - Приступайте к миганию.
Уменьшите требования к хранению
Устройствам, у которых нет полного хранилища A/B, выделенного в super, и которые планируют использовать /data
по мере необходимости, настоятельно рекомендуется использовать инструмент сопоставления блоков. Инструмент сопоставления блоков обеспечивает единообразие распределения блоков между сборками, сокращая ненужные записи в снимок. Это описано в разделе «Уменьшение размера OTA ».
Методы OTA-сжатия
Пакеты OTA можно настроить под различные показатели производительности. Android предоставляет несколько поддерживаемых методов сжатия ( gz
, lz4
, zstd
и none
), которые имеют компромисс между временем установки, использованием пространства COW, временем загрузки и временем слияния снимков. Опцией по умолчанию, включенной для виртуального ab со сжатием, является gz compression method
. (Примечание: относительная производительность между методами сжатия варьируется в зависимости от скорости процессора и пропускной способности хранилища, которая может меняться в зависимости от устройства. Все пакеты OTA, созданные ниже, имеют отключенную PostInstall, что немного замедляет время загрузки. Общий размер динамического раздела полной ota. без сжатия составляет 4,81 ГБ ).
Дополнительный OTA на Pixel 6 Pro
Время установки без учета постустановочной фазы | Использование пространства COW | Время загрузки после OTA | Время слияния снимков | |
---|---|---|---|---|
гз | 24 мин. | 1,18 ГБ | 40,2 сек. | 45,5 сек. |
лз4 | 13 мин. | 1,49 ГБ | 37,4 сек. | 37,1 сек. |
никто | 13 мин. | 2,90 ГБ | 37,6 сек. | 40,7 сек. |
Полное OTA на Pixel 6 Pro
Время установки без учета постустановочной фазы | Использование пространства COW | Время загрузки после OTA | Время слияния снимков | |
---|---|---|---|---|
гз | 23 мин. | 2,79 ГБ | 24,9 сек. | 41,7 сек. |
лз4 | 12 мин. | 3,46 ГБ | 20,0 сек. | 25,3 сек. |
никто | 10 минут | 4,85 ГБ | 20,6 сек. | 29,8 сек. |