Para implementar A/B virtual em um novo dispositivo ou para atualizar 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, defina-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 apenas da 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 superior, para habilitar 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
e brotli
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz
Para o Android 12, para habilitar 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 superior, o recurso de compactação XOR não é 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
.
Fusão do espaço do usuário
Para dispositivos atualizados para o Android 13 e superior, o processo de mesclagem do espaço do usuário, conforme descrito em Camadas do mapeador de dispositivos, não é ativado por padrão. Para habilitar 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 iniciados com 13 e superior.
Controle de inicialização HAL
O HAL de controle de inicialização fornece uma interface para clientes OTA controlarem os 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 o flashing/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 f2fs: export FS_NOCOW_FL flag to user kernel patch to fix file pinning. Inclua o f2fs: suporte ao patch de kernel de arquivo fixado alinhado também.
O Virtual A/B conta com recursos adicionados na versão 4.3 do kernel: o bit de status de estouro no snapshot
e os destinos snapshot-merge
. Todos os dispositivos iniciados com Android 9 e posterior já devem ter a versão do kernel 4.4 ou posterior.
Para habilitar instantâneos compactados, a versão mínima do kernel compatível é 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 ramdisk de primeiro estágio. Isso pode ser feito adicionando a seguinte linha ao Makefile do dispositivo:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Retrofitting em dispositivos atualizando para o 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 para dispositivos iniciados 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 de atualização, sempre há espaço suficiente na super partição para que o arquivo COW nunca seja criado em/data
.Sinalizadores de recursos de tempo de construção — Para dispositivos que adaptam o A/B virtual,
PRODUCT_VIRTUAL_AB_OTA
ePRODUCT_VIRTUAL_AB_OTA_RETROFIT
são definidos comotrue
, conforme mostrado abaixo:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Super tamanho da partição — Os dispositivos iniciados com A/B virtual podem cortar
BOARD_SUPER_PARTITION_SIZE
pela metade porque os slots B não estão na super partição. Os dispositivos que adaptam 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) + despesas gerais .
Alterações do carregador de inicialização
Durante a etapa de mesclagem de uma atualização, /data
contém a única instância inteira do sistema operacional Android. Após o início da migração, o system
nativo, vendor
e as partições product
ficam incompletos até que a cópia seja concluída. Se o dispositivo for redefinido para as configuraçõ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 poderá ser inicializado.
Antes de apagar /data
, conclua a mesclagem em recuperação ou reversão, dependendo do estado do dispositivo:
- Se a nova compilação inicializou com êxito 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, defina 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á ou não em andamento ou quais blocos em /data
constituem as partições do sistema operacional. Os dispositivos devem impedir que o usuário torne o dispositivo inoperável (bricking) inadvertidamente, fazendo o seguinte:
- Implemente o HAL de controle de inicialização para que o carregador de inicialização possa ler o valor definido pelo método
setSnapshotMergeStatus()
. - Se o status de mesclagem for
MERGING
, ou se o status de 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 de mesclagem devem 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 flash personalizados para
fastboot snapshot-update cancel
ao atualizar todo o dispositivo. Isso é seguro para emitir porque o flash de 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 de inicialização rápida
O Android 11 faz as seguintes alterações no protocolo fastboot:
-
getvar snapshot-update-status
— Retorna o valor que o controle de boot HAL comunicou ao bootloader:- Se o estado for
MERGING
, o bootloader deve retornarmerging
. - Se o estado for
SNAPSHOTTED
, o bootloader deve retornarsnapshotted
. - Caso contrário, o bootloader deve 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 somente sesnapshot-update-status
formerging
e só é suportado em fastbootd. -
snapshot-update cancel
— Define o status de mesclagem do HAL de controle de inicialização paraCANCELLED
. 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 deve 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 deve abortar a operação. O slot pode ser alterado com segurança no estadoSNAPSHOTTED
.
Essas alterações são projetadas para evitar que um dispositivo não inicialize acidentalmente, mas podem ser prejudiciais para ferramentas automatizadas. Quando os comandos são usados como um componente de atualização de todas as partições, como executar fastboot flashall
, é recomendável usar o seguinte fluxo:
- Consulta
getvar snapshot-update-status
. - Se
merging
ousnapshotted
, emitasnapshot-update cancel
. - Prossiga com as etapas intermitentes.
Reduzindo os requisitos de armazenamento
Os dispositivos que não têm 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 as compilações, reduzindo gravações desnecessárias no instantâneo. Isso está documentado em Redução do tamanho do OTA .
Métodos de compressão OTA
Os pacotes Ota podem ser ajustados para diferentes métricas de desempenho. Atualmente, o Android fornece alguns métodos de compactação suportados ( gz
, lz4
e none
) que têm compensações entre tempo de instalação, uso de espaço de vaca, tempo de inicialização e tempo de mesclagem de instantâneo. 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 desativado, 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 é de 4,81 GB )
1. OTA incremental no Pixel 6 Pro
Tempo de instalação sem fase de pós-instalação | Uso do espaço da vaca | Tempo de inicialização pós-OTA | Tempo de Mesclagem do Instantâneo | |
---|---|---|---|---|
gz | 24 minutos | 1,18 GB | 40,2 seg | 45,5 segundos |
lz4 | 13 minutos | 1,49 GB | 37,4 seg | 37,1 seg |
nenhum | 13 minutos | 2,90 GB | 37,6 seg | 40,7 seg |
2. OTA completo no Pixel 6 Pro
Tempo de instalação sem fase de pós-instalação | Uso do espaço da vaca | Tempo de inicialização pós-OTA | Tempo de Mesclagem do Instantâneo | |
---|---|---|---|---|
gz | 23 minutos | 2,79 GB | 24,9 seg | 41,7 seg |
lz4 | 12 minutos | 3,46 GB | 20,0 seg | 25,3 seg |
nenhum | 10 minutos | 4,85 GB | 20,6 seg | 29,8 seg |