Implementando o 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 da compilação e do carregador de inicialização para o Android 12.

Esse recurso fornece uma maneira de separar os parâmetros de configuração do espaço de usuário do Android daqueles para o 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 tem 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 inferior. 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 carregador de inicialização, consulte a implementação do carregador de inicialização de referência do U-boot do Cuttlefish. Dois commits na referência estão listados abaixo. O primeiro atualiza o suporte à versão do cabeçalho de inicialização para a versão mais recente. No exemplo, o primeiro commit atualiza (ou uprevs) o suporte de versão para o próximo, v4. A segunda faz duas coisas; ele adiciona manipulação de bootconfig e demonstra a adição de parâmetros em tempo de execução:

Exemplo de compilação

Para um exemplo de compilação que mostra as alterações do 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 Cuttlefish para fazer o seguinte:

Implementação

Os parceiros devem adicionar suporte a seus carregadores de inicialização e mover seus parâmetros androidboot.* em tempo de compilação do cmdline do kernel para o arquivo bootconfig. A melhor maneira de implementar essa 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 no arquivo /proc/cmdline os parâmetros androidboot.* , aponte-os 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.

Mudanças de construção

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

Alterações do carregador de inicialização

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

O carregador de inicialização 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
  • 4 parameters size
  • 4 Soma de parameters checksum de tamanho B
  • 12 B string mágica bootconfig ( #BOOTCONFIG\n )

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

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

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

Se você precisar adicionar quaisquer parâmetros após a aplicação do trailer bootconfig, sobrescreva 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 intocados 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 do jeito que 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 upgrade e downgrade OTA

Ao gerenciar atualizações e downgrades OTA entre diferentes versões do Android ou diferentes versões do kernel, deve-se tomar cuidado especial.

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

As versões do kernel 12-5.4 e posteriores suportam bootconfig. Se fizer downgrade para qualquer versão anterior (incluindo 11-5.4), os parâmetros cmdline do kernel devem 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 atualizar as 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 a 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, significa que houve um problema ao carregar o arquivo bootconfig. Para ver diferentes tipos de erro, veja init/main.c .