Suporte a atualizações OTA

Para oferecer suporte às atualizações over-the-air (OTA) , o carregador de inicialização deve ser capaz de acessar um disco RAM de recuperação durante a inicialização. Se o dispositivo usa uma imagem de recuperação AOSP não modificada, o bootloader lê os primeiros 32 bytes na partição misc ; se os dados lá corresponderem boot-recovery , o bootloader será inicializado na imagem recovery . Este método permite que qualquer trabalho de recuperação pendente (por exemplo, aplicar um OTA ou remover dados) continue até a conclusão.

Para obter detalhes sobre o conteúdo de um bloco em flash usado para comunicações pela recuperação e pelo bootloader, consulte bootable/recovery/bootloader_message/bootloader_message.h .

Dispositivos com atualizações A/B

Para oferecer suporte a atualizações OTA em dispositivos que usam atualizações A/B , certifique-se de que o carregador de inicialização do dispositivo atenda aos seguintes critérios.

Critérios gerais

  • Todas as partições atualizadas por meio de um OTA devem ser atualizáveis ​​enquanto o sistema principal é inicializado (e não atualizado na recuperação).

  • Para inicializar a partição do system , o bootloader passa o seguinte valor na linha de comando do kernel: ro root=/dev/[node] rootwait init=/init .

  • É responsabilidade da estrutura do Android chamar markBootSuccessful do HAL. O bootloader nunca deve marcar uma partição como inicializada com sucesso.

Suporte para HAL de controle de inicialização

O bootloader deve suportar o boot_control HAL conforme definido em hardware/libhardware/include/hardware/boot_control.h ). O atualizador consulta o HAL de controle de inicialização , atualiza o slot de inicialização que não está em uso no momento, altera o slot ativo usando o HAL e reinicializa no sistema operacional atualizado. Para obter detalhes, consulte Implementando o HAL de controle de inicialização .

Suporte para slots

O bootloader deve suportar funcionalidades relacionadas a partições e slots, incluindo:

  • Os nomes das partições devem incluir um sufixo que identifique quais partições pertencem a um determinado slot no bootloader. Para cada partição, há uma variável correspondente has-slot: partition base name com um valor de yes . Os slots são nomeados alfabeticamente como a, b, c, etc. correspondentes às partições com o sufixo _a , _b , _c , etc. O gerenciador de inicialização deve informar ao sistema operacional qual slot foi inicializado usando a propriedade de linha de comando androidboot.slot_suffix . Essa propriedade é definida por meio do bootconfig para dispositivos iniciados com Android 12 ou posterior.

  • O valor slot-retry-count é redefinido para um valor positivo (geralmente 3 ), seja pelo controle de inicialização HAL por meio do retorno de chamada setActiveBootSlot ou pelo comando fastboot set_active . Ao modificar uma partição que faz parte de um slot, o bootloader limpa "inicializado com sucesso" e redefine a contagem de novas tentativas para o slot.

O bootloader também deve determinar qual slot carregar. A figura mostra um exemplo de processo de decisão.

Fluxo de alocação do carregador de inicialização
Figura 1. Fluxo de alocação do carregador de inicialização
  1. Determine qual slot tentar. Não tente carregar um slot marcado como slot-unbootable . Esse slot deve ser consistente com os valores retornados pelo fastboot e é chamado de slot atual.

  2. Se o slot atual não estiver marcado como slot-successful e tiver um slot-retry-count = 0 , marque o slot atual como slot-unbootable . Em seguida, selecione um slot diferente que não esteja marcado unbootable e esteja marcado como slot-successful ; este slot agora é o slot selecionado. Se nenhum slot atual estiver disponível, inicialize para recuperação ou exiba uma mensagem de erro significativa para o usuário.

  3. Selecione o boot.img apropriado e inclua o caminho para corrigir a partição do sistema na linha de comando do kernel.

  4. Preencha o parâmetro slot_suffix da linha de comando do kernel.

  5. Bota. Se não estiver marcado slot-successful , diminua slot-retry-count .

O utilitário fastboot determina qual partição piscar ao executar qualquer comando flash. Por exemplo, executar o comando fastboot flash system system.img primeiro consulta a variável current-slot e concatena o resultado ao sistema para gerar o nome da partição que deve ser atualizada ( system_a , system_b , etc.).

Ao definir o slot atual usando o comando fastboot set_active ou o comando HAL setActiveBootSlot de controle de inicialização, o carregador de inicialização deve atualizar o slot atual, limpar slot-unbootable e slot-successful e redefinir a contagem de novas tentativas (essa é a única maneira de limpar slot-unbootable ).

Dispositivos sem atualizações A/B

Para oferecer suporte a atualizações OTA em dispositivos que não usam atualizações A/B (consulte Dispositivos atualizáveis ​​não A/B ), verifique se o carregador de inicialização do dispositivo atende aos critérios a seguir.

  • A partição recovery deve conter uma imagem capaz de ler uma imagem do sistema de alguma partição suportada ( cache , userdata ) e gravá-la na partição system .

  • O bootloader deve suportar a reinicialização diretamente no modo de recuperação.

  • Se as atualizações de imagem de rádio forem suportadas, a partição recovery também deve ser capaz de atualizar o rádio. Isso pode ser feito de uma das duas maneiras:

    • O bootloader pisca o rádio. Nesse caso, deve ser possível reinicializar a partir da partição de recuperação de volta ao gerenciador de inicialização para concluir a atualização.

    • A imagem de recuperação pisca no rádio. Essa funcionalidade pode ser fornecida como uma biblioteca ou utilitário binário.