Para implementar A/B virtual em um novo dispositivo ou para modernizar um dispositivo iniciado, você deve fazer alterações no código específico do dispositivo.
Construir bandeiras
Os dispositivos que usam A/B virtual devem ser configurados como um dispositivo A/B e devem ser iniciados com partições dinâmicas .
Para dispositivos iniciados com A/B virtual, configure-os para herdar a configuração básica do dispositivo A/B virtual:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
Os dispositivos iniciados com A/B virtual precisam de apenas metade do tamanho da placa para BOARD_SUPER_PARTITION_SIZE
porque os slots B não estão mais em super. Ou seja, BOARD_SUPER_PARTITION_SIZE
deve ser maior ou igual a sum(size of update groups) + overhead , que, por sua vez, deve ser maior ou igual a sum(size of partitions) + overhead .
Para Android 13 e versões mais recentes, para ativar snapshots compactados com Virtual A/B, herde a seguinte configuração básica:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)
Isso permite instantâneos do espaço do usuário com Virtual A/B ao usar um método de compactação não operacional. Você pode então configurar o método de compactação para um dos métodos suportados, gz
, zstd
e lz4
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
No Android 12, para ativar snapshots compactados com Virtual A/B, herde a seguinte configuração básica:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
Compressão XOR
Para dispositivos atualizados para Android 13 e versões posteriores, o recurso de compactação XOR não está ativado por padrão. Para ativar a compactação XOR, adicione o seguinte ao arquivo .mk
do dispositivo.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
A compactação XOR é habilitada por padrão para dispositivos que herdam de android_t_baseline.mk
.
Mesclagem do espaço do usuário
Para dispositivos atualizados para o Android 13 e versões mais recentes, o processo de mesclagem do espaço do usuário, conforme descrito em Camadas do mapeador de dispositivos, não está ativado por padrão. Para ativar a mesclagem do espaço do usuário, adicione a seguinte linha ao arquivo .mk
do dispositivo:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
A mesclagem do espaço do usuário é habilitada por padrão em dispositivos lançados com 13 e superior.
Controle de inicialização HAL
O HAL de controle de inicialização fornece uma interface para clientes OTA controlarem slots de inicialização. O Virtual A/B requer uma atualização de versão secundária do HAL de controle de inicialização porque APIs adicionais são necessárias para garantir que o carregador de inicialização esteja protegido durante a atualização/redefinição de fábrica. Consulte IBootControl.hal e types.hal para obter a versão mais recente da definição 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
}
Mudanças no Fstab
A integridade da partição de metadados é essencial para o processo de inicialização, especialmente logo após a aplicação de uma atualização OTA. Portanto, a partição de metadados deve ser verificada antes de first_stage_init
montá-la. Para garantir que isso aconteça, adicione o sinalizador check
fs_mgr à entrada para /metadata
. O seguinte fornece um exemplo:
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check
Requisitos do kernel
Para ativar a captura instantânea, defina CONFIG_DM_SNAPSHOT
como true
.
Para dispositivos que usam F2FS, inclua o sinalizador f2fs: export FS_NOCOW_FL para o patch do kernel do usuário para corrigir a fixação de arquivos. Inclua também o f2fs: suporte ao patch do kernel de arquivo fixado alinhado .
O Virtual A/B depende de recursos adicionados na versão 4.3 do kernel: o bit de status de overflow nos destinos snapshot
e snapshot-merge
. Todos os dispositivos lançados com Android 9 e posterior já devem ter kernel versão 4.4 ou posterior.
Para ativar instantâneos compactados, a versão mínima do kernel suportada é 4.19. Defina CONFIG_DM_USER=m
ou CONFIG_DM_USER=y
. Se estiver usando o primeiro (um módulo), o módulo deve ser carregado no disco RAM do primeiro estágio. Isso pode ser conseguido adicionando a seguinte linha ao Makefile do dispositivo:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Retrofit em dispositivos atualizados para Android 11
Ao atualizar para o Android 11, os dispositivos iniciados com partições dinâmicas podem, opcionalmente, atualizar o A/B virtual. O processo de atualização é basicamente o mesmo dos dispositivos lançados com A/B virtual, com algumas pequenas diferenças:
Localização dos arquivos COW — Para dispositivos de inicialização, o cliente OTA usa todo o espaço vazio disponível na superpartição antes de usar o espaço em
/data
. Para dispositivos retroajustados, sempre há espaço suficiente na superpartição para que o arquivo COW nunca seja criado em/data
.Sinalizadores de recursos em tempo de construção — Para dispositivos que atualizam A/B virtual, tanto
PRODUCT_VIRTUAL_AB_OTA
quantoPRODUCT_VIRTUAL_AB_OTA_RETROFIT
são definidos comotrue
, conforme mostrado abaixo:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Tamanho da superpartição — Dispositivos iniciados com A/B virtual podem cortar
BOARD_SUPER_PARTITION_SIZE
pela metade porque os slots B não estão na superpartição. Os dispositivos que atualizam o A/B virtual mantêm o antigo tamanho da superpartição, entãoBOARD_SUPER_PARTITION_SIZE
é maior ou igual a 2 * sum(size of update groups) + overhead , que por sua vez é maior ou igual a 2 * sum(size of partitions) + sobrecarga .
Mudanças no bootloader
Durante a etapa de mesclagem de uma atualização, /data
contém a única instância completa do sistema operacional Android. Assim que a migração for iniciada, as partições nativas do system
, vendor
e product
ficarão incompletas até que a cópia seja concluída. Se o dispositivo for redefinido para os padrões de fábrica durante esse processo, seja por recuperação ou por meio da caixa de diálogo Configurações do sistema, o dispositivo não será inicializável.
Antes de apagar /data
, conclua a mesclagem na recuperação ou reversão dependendo do estado do dispositivo:
- Se a nova compilação foi inicializada com sucesso antes, conclua a migração.
- Caso contrário, reverta para o slot antigo:
- Para partições dinâmicas, reverta para o estado anterior.
- Para partições estáticas, configure o slot ativo para o slot antigo.
Tanto o bootloader quanto fastbootd
podem apagar a partição /data
se o dispositivo estiver desbloqueado. Embora fastbootd
possa forçar a conclusão da migração, o bootloader não pode. O bootloader não sabe se uma mesclagem está em andamento ou quais blocos em /data
constituem as partições do sistema operacional. Os dispositivos devem impedir que o usuário inadvertidamente torne o dispositivo inoperante (bricking), fazendo o seguinte:
- Implemente o HAL de controle de inicialização para que o bootloader possa ler o valor definido pelo método
setSnapshotMergeStatus()
. - Se o status da mesclagem for
MERGING
ou se o status da mesclagem forSNAPSHOTTED
e o slot tiver mudado para o slot recém-atualizado, as solicitações para limparuserdata
,metadata
ou a partição que armazena o status da mesclagem deverão ser rejeitadas no bootloader. - Implemente o comando
fastboot snapshot-update cancel
para que os usuários possam sinalizar ao bootloader que desejam ignorar esse mecanismo de proteção. - Modifique ferramentas ou scripts de atualização personalizados para emitir
fastboot snapshot-update cancel
ao atualizar o dispositivo inteiro. É seguro emitir isso porque atualizar todo o dispositivo remove o OTA. As ferramentas podem detectar esse comando em tempo de execução implementandofastboot getvar snapshot-update-status
. Este comando ajuda a diferenciar as condições de erro.
Exemplo
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()));
}
Mudanças nas ferramentas do Fastboot
O Android 11 faz as seguintes alterações no protocolo fastboot:
-
getvar snapshot-update-status
— Retorna o valor que o HAL de controle de inicialização comunicou ao bootloader:- Se o estado for
MERGING
, o bootloader deverá retornarmerging
. - Se o estado for
SNAPSHOTTED
, o bootloader deverá retornarsnapshotted
. - Caso contrário, o bootloader deverá retornar
none
.
- Se o estado for
-
snapshot-update merge
— Conclui uma operação de mesclagem, inicializando em recovery/fastbootd se necessário. Este comando é válido apenas sesnapshot-update-status
estivermerging
e só é compatível com fastbootd. -
snapshot-update cancel
— Define o status de mesclagem do HAL de controle de inicialização comoCANCELLED
. Este comando é inválido quando o dispositivo está bloqueado. -
erase
ouwipe
— Umerase
ouwipe
demetadata
,userdata
ou uma partição que contém o status de mesclagem para o HAL de controle de inicialização deve verificar o status de mesclagem do instantâneo. Se o status forMERGING
ouSNAPSHOTTED
, o dispositivo deverá abortar a operação. -
set_active
— Um comandoset_active
que altera o slot ativo deve verificar o status de mesclagem do instantâneo. Se o status forMERGING
, o dispositivo deverá abortar a operação. O slot pode ser alterado com segurança no estadoSNAPSHOTTED
.
Essas alterações foram projetadas para evitar que um dispositivo não inicialize acidentalmente, mas podem prejudicar as ferramentas automatizadas. Quando os comandos são usados como um componente de atualização de todas as partições, como executar fastboot flashall
, é recomendado usar o seguinte fluxo:
- Consulte
getvar snapshot-update-status
. - Se for
merging
ousnapshotted
, emitasnapshot-update cancel
. - Prossiga com as etapas intermitentes.
Reduza os requisitos de armazenamento
Dispositivos que não possuem armazenamento A/B completo alocado em super e esperam usar /data
conforme necessário são altamente recomendados para usar a ferramenta de mapeamento de blocos. A ferramenta de mapeamento de blocos mantém a alocação de blocos consistente entre compilações, reduzindo gravações desnecessárias no instantâneo. Isso está documentado em Reduzindo o tamanho do OTA .
Métodos de compressão OTA
Os pacotes OTA podem ser ajustados para diferentes métricas de desempenho. O Android fornece vários métodos de compactação suportados ( gz
, lz4
, zstd
e none
) que têm compensações entre tempo de instalação, uso de espaço COW, tempo de inicialização e tempo de mesclagem de snapshot. A opção padrão habilitada para ab virtual com compactação é o gz compression method
. (Observação: o desempenho relativo entre os métodos de compactação varia dependendo da velocidade da CPU e da taxa de transferência de armazenamento, que pode mudar dependendo do dispositivo. Todos os pacotes OTA gerados abaixo estão com o PostInstall desabilitado, o que diminuirá um pouco o tempo de inicialização. O tamanho total da partição dinâmica de um ota completo sem compactação é 4,81 GB ).
OTA incremental no Pixel 6 Pro
Tempo de instalação sem fase pós-instalação | Uso de espaço COW | Tempo de inicialização pós-OTA | Tempo de mesclagem do instantâneo | |
---|---|---|---|---|
gz | 24 minutos | 1,18 GB | 40,2 segundos | 45,5 segundos |
lz4 | 13 minutos | 1,49 GB | 37,4 segundos | 37,1 segundos |
nenhum | 13 minutos | 2,90GB | 37,6 segundos | 40,7 segundos |
OTA completo no Pixel 6 Pro
Tempo de instalação sem fase pós-instalação | Uso do espaço COW | Tempo de inicialização pós-OTA | Tempo de mesclagem do instantâneo | |
---|---|---|---|---|
gz | 23 minutos | 2,79GB | 24,9 segundos | 41,7 segundos |
lz4 | 12 minutos | 3,46GB | 20,0 segundos | 25,3 segundos |
nenhum | 10 minutos | 4,85GB | 20,6 segundos | 29,8 segundos |