Suporte a atualizações OTA

Para suportar atualizações over-the-air (OTA) , o bootloader 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 bootloader lerá os primeiros 32 bytes na partição misc ; se os dados corresponderem boot-recovery , o bootloader inicializará na imagem recovery . Este método permite que qualquer trabalho de recuperação pendente (por exemplo, aplicação de OTA ou remoção de 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 critérios a seguir.

Critérios gerais

  • Todas as partições atualizadas através de um OTA devem ser atualizáveis ​​enquanto o sistema principal é inicializado (e não atualizadas 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 controle de inicialização HAL

O bootloader deve suportar o HAL boot_control 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 slot específico no bootloader. Para cada partição, há uma variável correspondente has-slot: partition base name com um valor yes . Os slots são nomeados em ordem alfabética como a, b, c, etc. correspondendo a partições com o sufixo _a , _b , _c , etc. O bootloader deve informar ao sistema operacional qual slot foi inicializado usando a propriedade de linha de comando androidboot.slot_suffix . Esta 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 por meio do 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 do slot.

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

Fluxo de slot do bootloader
Figura 1. Fluxo de slot do bootloader
  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 slot-retry-count = 0 , marque o slot atual como slot-unbootable . Em seguida, selecione um slot diferente que não esteja marcado unbootable e que 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 ao 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 atualizar ao executar qualquer comando flash. Por exemplo, executar o comando fastboot flash system system.img primeiro consulta a variável current-slot e depois 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 de controle de inicialização HAL setActiveBootSlot , o carregador de inicialização deve atualizar o slot atual, limpar slot-unbootable e slot-successful e redefinir a contagem de novas tentativas (esta é 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 ), certifique-se de que o carregador de inicialização do dispositivo atenda aos critérios a seguir.

  • A partição recovery deve conter uma imagem que seja 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 deverá ser capaz de atualizar o rádio. Isso pode ser feito de duas maneiras:

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

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