Suporte a atualizações OTA

Para oferecer suporte às atualizações OTA (over-the-air) , o carregador de inicialização deve ser capaz de acessar um disco RAM de recuperação durante a inicialização. Se o dispositivo usar uma imagem de recuperação AOSP não modificada, o carregador de inicialização lerá os primeiros 32 bytes na partição misc ; se os dados lá corresponderem boot-recovery , o bootloader inicializará na imagem de recovery . Esse 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 por recuperação e o carregador de inicialização, 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 , verifique se o carregador de inicialização do dispositivo atende aos critérios a seguir.

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 atualizados na recuperação).

  • Para inicializar a partição do system , o carregador de inicialização 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 controle de inicialização HAL

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 oferecer suporte a 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 carregador de inicialização. 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 carregador 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 de 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 por meio do comando fastboot set_active . Ao modificar uma partição que faz parte de um slot, o carregador de inicialização limpa "inicializado com sucesso" e redefine a contagem de 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 como não unbootable e 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 for marcado slot-successful , diminua slot-retry-count .

O utilitário fastboot determina qual partição deve ser flash ao executar qualquer comando flash. Por exemplo, executar o comando fastboot flash system system.img primeiro consulta a variável current-slot , em seguida, concatena o resultado para system 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 boot control HAL setActiveBootSlot , o carregador de inicialização deve atualizar o slot atual, limpar slot-unbootable e slot-successful e redefinir a contagem de 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 de 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 do system .

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

  • Se houver suporte para atualizações de imagem de rádio, a partição de recovery também deverá ser capaz de fazer o flash do rádio. Isso pode ser feito de 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 carregador de inicialização para concluir a atualização.

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