Implementando Bootconfig no Android 12

No Android 12, o recurso bootconfig substitui as opções de cmdline do kernel androidboot.* em uso com o Android 11 e versões anteriores. O recurso bootconfig é um mecanismo para passar detalhes de configuração do build e do bootloader para o Android 12.

Este recurso fornece uma maneira de separar os parâmetros de configuração do espaço do usuário Android daqueles do kernel. Mover os longos parâmetros do kernel androidboot.* para o arquivo bootconfig cria espaço no cmdline do kernel e o torna disponível para fácil expansão futura.

Tanto o kernel quanto o espaço de usuário do Android devem suportar bootconfig .

  • Primeira versão que tem esse suporte: Android 12
  • Primeira versão do kernel que possui este suporte: kernel 12-5.4.xx

Implemente o recurso bootconfig para novos dispositivos lançados com uma versão de kernel 12-5.10.xx. Você não precisa implementá-lo se estiver atualizando dispositivos.

Exemplos e fonte

Ao visualizar os exemplos e o código-fonte nesta seção, observe que o formato do código bootconfig é apenas um pouco diferente do formato do cmdline do kernel usado no Android 11 e versões anteriores. No entanto, a seguinte diferença é importante para o seu uso:

  • Os parâmetros devem ser separados pela sequência de escape de nova linha \n , não por espaços.

Exemplo de carregador de inicialização

Para obter um exemplo de bootloader, consulte a implementação do bootloader de referência do Cuttlefish U-boot. Dois commits na referência estão listados abaixo. O primeiro atualiza o suporte da versão do cabeçalho de inicialização para a versão mais recente. No exemplo, o primeiro commit atualiza (ou uprevs) o suporte da versão para o próximo, v4. A segunda faz duas coisas; adiciona manipulação de bootconfig e demonstra a adição de parâmetros em tempo de execução:

Exemplo de construção

Para obter um exemplo de compilação que mostra as alterações mkbootimg para compilar o vendor_boot.img com o cabeçalho de inicialização do fornecedor v4, consulte mkbootimg changes for bootconfig . Veja as alterações do Choco para fazer o seguinte:

Implementação

Os parceiros devem adicionar suporte aos seus bootloaders e mover seus parâmetros androidboot.* em tempo de compilação do cmdline do kernel para o arquivo bootconfig. A melhor maneira de implementar esta mudança é fazê-lo de forma incremental; consulte a seção Implementação e validação incremental para obter informações sobre como seguir um processo incremental.

Se você tiver alterações que pesquisam parâmetros androidboot.* no arquivo /proc/cmdline, aponte-as para o arquivo /proc/bootconfig. As propriedades ro.boot.* são definidas com os novos valores bootconfig , portanto, você não precisa fazer alterações no código usando essas propriedades.

Construir mudanças

Primeiro, atualize sua versão do cabeçalho de inicialização para a versão 4:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

Adicione o parâmetro cmdline do kernel bootconfig . Isso faz com que o kernel procure a seção bootconfig:

BOARD_KERNEL_CMDLINE += bootconfig

Os parâmetros bootconfig são criados a partir dos parâmetros na variável BOARD_BOOTCONFIG , assim como o cmdline do kernel é criado a partir de BOARD\_KERNEL\_CMDLINE .

Qualquer parâmetro androidboot.* pode ser movido como está, semelhante ao seguinte:

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

Mudanças no carregador de inicialização

O bootloader configura o initramfs antes de pular para o kernel. A configuração de inicialização do kernel procura a seção bootconfig e procura que ela esteja bem no final do initramfs, com o trailer esperado.

O bootloader obtém as informações de layout vendor_boot.img do cabeçalho da imagem de inicialização do fornecedor.

Diagram of bootconfig memory allocation layout

Figura 1. Alocação de memória bootconfig do Android 12

O bootloader cria a seção bootconfig na memória. A seção bootconfig contém alocações de memória para o seguinte:

  • Parâmetros
  • parameters size de tamanho 4 B
  • parameters checksum de tamanho 4 B
  • String mágica de bootconfig de 12 B ( #BOOTCONFIG\n )

Os parâmetros vêm de duas fontes: parâmetros conhecidos em tempo de construção e parâmetros que não são conhecidos em tempo de construção. Parâmetros desconhecidos devem ser adicionados.

Os parâmetros conhecidos no momento da construção são empacotados no final da imagem vendor_boot na seção bootconfig. O tamanho da seção é armazenado (como bytes) no campo do cabeçalho de inicialização do fornecedor vendor_bootconfig_size .

Os parâmetros que não são conhecidos em tempo de construção só são conhecidos em tempo de execução no bootloader. Eles devem ser adicionados ao final da seção de parâmetros do bootconfig antes que o trailer do bootconfig seja aplicado.

Se você precisar adicionar algum parâmetro após a aplicação do trailer bootconfig, substitua o trailer e aplique-o novamente.

Implementação e validação incrementais

Implemente o recurso bootconfig de forma incremental seguindo o processo fornecido nesta seção. Deixe os parâmetros cmdline do kernel intactos enquanto os parâmetros bootconfig são adicionados.

Estes são os passos para uma implementação incremental, com validação:

  1. Faça as alterações no bootloader e na compilação e faça o seguinte:
    1. Use a variável BOARD_BOOTCONFIG para adicionar um novo parâmetro bootconfig.
    2. Mantenha os parâmetros cmdline do kernel como estão, para que o dispositivo possa continuar a inicializar corretamente. Isso torna a depuração e a validação muito mais fáceis.
  2. Verifique seu trabalho verificando o conteúdo de /proc/bootconfig . Verifique se você vê o parâmetro recém-adicionado após a inicialização do dispositivo.
  3. Mova os parâmetros androidboot.* do cmdline do kernel para bootconfig, usando a variável BOARD_BOOTCONFIG e o bootloader.
  4. Verifique se cada um dos parâmetros existe em /proc/bootconfig E se eles não estão em /proc/cmdline . Se você puder verificar isso, sua implementação foi bem-sucedida.

Considerações sobre atualização e downgrade de OTA

Ao gerenciar atualizações e downgrades OTA entre diferentes versões do Android ou diferentes versões do kernel, cuidados especiais devem ser tomados.

Android 12 é a primeira versão com suporte bootconfig. Se estiver fazendo downgrade para qualquer versão anterior, os parâmetros cmdline do kernel deverão ser usados ​​em vez do bootconfig.

As versões 12-5.4 do kernel e posteriores suportam bootconfig. Se estiver fazendo downgrade para qualquer versão anterior (incluindo 11-5.4), os parâmetros cmdline do kernel deverão ser usados.

As atualizações do Android 11 e anteriores para o Android 12 e posteriores podem continuar usando os parâmetros cmdline do kernel. O mesmo vale para a atualização de versões do kernel.

Solução de problemas

Ao executar a etapa de verificação , se você não vir os parâmetros esperados em /proc/bootconfig , verifique os logs do kernel em logcat . Sempre há uma entrada de log presente para bootconfig se o kernel suportar.

Exemplo de saída de registro

$ adb logcat | grep bootconfig
02-24 17:00:07.610     0     0 I Load bootconfig: 128 bytes 9 nodes

Se você vir um log de erros retornado, então houve um problema ao carregar o bootconfig. Para ver diferentes tipos de erros, veja init/main.c .