O Android 9 introduziu um campo de versão no cabeçalho da imagem de inicialização, permitindo atualizações no cabeçalho, mantendo a compatibilidade com versões anteriores. O carregador de inicialização precisa verificar o campo de versão do cabeçalho e analisar o cabeçalho corretamente. Dispositivos lançados com:
- O Android 13 pode usar a versão 3 ou 4 do cabeçalho de inicialização. Para
dispositivos com suporte à arquitetura
Generic Kernel Image
(GKI), a versão 4 é a imagem de inicialização principal e o campo
os_version
no cabeçalho de inicialização precisa ser zero. O carregador de inicialização do dispositivo precisa receber as informações da versão das propriedades da Inicialização verificada do Android (AVB, na sigla em inglês). - O Android 12 pode usar a versão 3 ou 4 do cabeçalho de inicialização. Para dispositivos com suporte à arquitetura Generic Kernel Image (GKI), a versão 4 é a imagem de inicialização principal.
- O Android 11 pode usar a versão 3 do cabeçalho de inicialização. Para dispositivos com suporte à arquitetura Generic Kernel Image (GKI), essa versão precisa ser usada para a imagem de inicialização principal.
- O Android 10 precisa usar a versão 2 do cabeçalho de inicialização.
- O Android 9 precisa usar a versão 1 do cabeçalho de inicialização.
- O Android 8 e versões anteriores usam a versão 0 do cabeçalho da imagem de inicialização.
Em todos os dispositivos com o Android 9 ou versões mais recentes, o
Pacote de testes de fornecedor (VTS, na sigla em inglês) verifica o formato da
imagem boot/recovery
para garantir que o cabeçalho da imagem de inicialização use a versão
correta. Para conferir detalhes do AOSP em todos os cabeçalhos de imagem de inicialização
e do fornecedor compatíveis, consulte
system/tools/mkbootimg/include/bootimg/bootimg.h
.
Implementar o controle de versões do cabeçalho da imagem de inicialização
A ferramenta mkbootimg
aceita os argumentos a seguir.
Argumento | Descrição |
---|---|
header_version |
Define a versão do cabeçalho da imagem de inicialização. Uma imagem de inicialização com uma versão de cabeçalho:
|
recovery_dtbo |
Usado para arquiteturas que utilizam DTB. Especifica o caminho para a imagem de
DTBO de recuperação. Opcional para dispositivos A/B, que não precisam de uma imagem de recuperação.
Dispositivos não A/B que usam header_version :
|
recovery_acpio |
Usado para arquiteturas que usam ACPI em vez de DTB. Especifica o caminho
para a imagem ACPIO de recuperação. Opcional para dispositivos A/B, que não precisam de uma
imagem de recuperação. Dispositivos não A/B que usam header_version :
|
dtb |
Caminho para a imagem DTB incluída nas imagens de inicialização/recuperação. |
dtb_offset |
Quando adicionado ao argumento base , fornece o endereço de carregamento físico para a árvore de dispositivos final. Por exemplo, se o argumento base
for 0x10000000 e o argumento dtb_offset
for 0x01000000 , o dtb_addr_field no cabeçalho da imagem de inicialização
será preenchido como 0x11000000 . |
O dispositivo BoardConfig.mk
usa a configuração BOARD_MKBOOTIMG_ARGS
para adicionar
header version
aos outros argumentos específicos da placa de mkbootimg
. Por
exemplo:
BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)
O sistema de build do Android usa a variável BoardConfig
BOARD_PREBUILT_DTBOIMAGE
para definir o argumento recovery_dtbo
da
ferramenta mkbootimg
durante a criação da imagem de recuperação. Para ver detalhes sobre as
mudanças no Android Open Source Project (AOSP), consulte as listas de mudanças associadas
para o controle de versões do cabeçalho
da imagem de inicialização.
Cabeçalho da imagem de inicialização, versão 4
O Android 12 fornece uma boot_signature
no cabeçalho da imagem de inicialização
versão 4, que pode ser usada para verificar a integridade do kernel e do
ramdisk. A verificação é feita em
VtsSecurityAvbTest
e é necessária para dispositivos que usam a arquitetura GKI. No entanto, o
boot_signature
não está envolvido no processo de inicialização verificada específico do dispositivo
e é usado apenas no VTS. Consulte a configuração da placa boot.img
GKI
e as configurações de inicialização
verificada do GKI
para mais detalhes.
A versão 4 do cabeçalho da imagem de inicialização do fornecedor oferece suporte a vários fragmentos do ramdisk do fornecedor.
A versão 4 da versão do cabeçalho da imagem de inicialização usa o formato a seguir.
struct boot_img_hdr
{
#define BOOT_MAGIC_SIZE 8
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t ramdisk_size; /* size in bytes */
uint32_t os_version;
uint32_t header_size; /* size of boot image header in bytes */
uint32_t reserved[4];
uint32_t header_version; /* offset remains constant for version check */
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
uint8_t cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE];
uint32_t signature_size; /* size in bytes */
};
Cabeçalho da imagem de inicialização, versão 3
O Android 11 atualiza o cabeçalho da imagem de inicialização para a versão 3, que remove os seguintes dados:
Carregador de inicialização de segundo estágio. Os campos
second_size
esecond_addr
não são mais exibidos no cabeçalho da imagem de inicialização. Dispositivos com um carregador de inicialização de segundo estágio precisam armazená-lo na própria partição.Imagem de recuperação. O requisito para especificar uma imagem de recuperação foi descontinuado, e os campos
recovery_dtbo_size
,recovery_dtbo_offset
,recovery_acpio_size
erecovery_acpio_offset
não aparecem mais no cabeçalho da imagem de inicialização.Os dispositivos A/B usam um esquema de atualização e recuperação que torna desnecessária a especificação de uma imagem DTBO ou ACPIO para recuperação.
Dispositivos não A/B que queiram especificar uma imagem de recuperação (DTBO ou ACPIO) precisam usar a versão 1 ou 2 do cabeçalho da imagem de inicialização.
blob da árvore de dispositivos (DTB, na sigla em inglês). O DTB é armazenado na partição de inicialização do fornecedor. Portanto, os campos
dtb_size
edtb_addr
não aparecem mais no cabeçalho da imagem de inicialização, mas estão presentes no cabeçalho dessa imagem.
Os dispositivos podem usar a versão 3 do cabeçalho da imagem de inicialização para obedecer à arquitetura
Generic Kernel Image
(GKI),
que unifica o kernel principal e move os módulos do fornecedor necessários para
a inicialização para a partição vendor_boot
. Isso significa que a imagem de inicialização contém apenas componentes
de GKI. Dispositivos que:
Usar GKI (requer o kernel android-4.19 ou android-5.4), mas não usar atualizações A/B, pode especificar uma imagem de recuperação usando a versão 3 da imagem de inicialização para a imagem de inicialização e a versão 2 da imagem de inicialização para a imagem de recuperação.
Não usar GKI e atualizações A/B podem especificar uma imagem de recuperação usando a versão 1 ou 2 da imagem de inicialização para as imagens de inicialização e de recuperação.
A versão 3 da versão do cabeçalho da imagem de inicialização usa o formato a seguir.
struct boot_img_hdr
{
#define BOOT_MAGIC_SIZE 8
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t ramdisk_size; /* size in bytes */
uint32_t os_version;
uint32_t header_size; /* size of boot image header in bytes */
uint32_t reserved[4];
uint32_t header_version; /* offset remains constant for version check */
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
uint8_t cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE];
};
Cabeçalho da imagem de inicialização, versão 2
O Android 10 atualiza o cabeçalho da imagem de inicialização para a versão 2, que adiciona uma seção para informações de recuperação de imagem DTB (tamanho da imagem e endereço de carregamento físico).
A versão 2 do cabeçalho da imagem de inicialização usa o formato a seguir.
struct boot_img_hdr
{
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
uint32_t header_version;
uint32_t os_version;
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
uint8_t cmdline[BOOT_ARGS_SIZE];
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
uint32_t recovery_[dtbo|acpio]_size; /* size of recovery image */
uint64_t recovery_[dtbo|acpio]_offset; /* offset in boot image */
uint32_t header_size; /* size of boot image header in bytes */
uint32_t dtb_size; /* size of dtb image */
uint64_t dtb_addr; /* physical load address */
};
Cabeçalho da imagem de inicialização, versão 1
O Android 9 converte o campo unused
do cabeçalho da imagem de inicialização
em um campo de versão do cabeçalho. Os dispositivos lançados com o Android 9 precisam usar o cabeçalho da imagem de inicialização com a versão do cabeçalho definida como 1 ou mais recente. Isso é verificado pelo VTS.
A versão 1 do cabeçalho da imagem de inicialização usa o formato abaixo.
struct boot_img_hdr
{
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
uint32_t header_version;
uint32_t os_version;
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
uint8_t cmdline[BOOT_ARGS_SIZE];
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
uint32_t recovery_[dtbo|acpio]_size; /* size of recovery image */
uint64_t recovery_[dtbo|acpio]_offset; /* offset in boot image */
uint32_t header_size; /* size of boot image header in bytes */
};
Dispositivos não A/B podem especificar uma imagem de sobreposição DTB/ACPI para recuperação para ajudar a reduzir as falhas de atualização over the air (OTA). Dispositivos A/B não têm esse problema e não precisam especificar uma imagem de sobreposição. É possível especificar uma imagem DTBO ou uma imagem ACPIO, mas não ambas (porque são usadas por arquiteturas diferentes). Para configurar o cabeçalho da imagem de inicialização corretamente, use:
Uma imagem de DTBO para recuperação, inclua os campos
recovery_dtbo_size
erecovery_dtbo_offset
(e não inclua os camposrecovery_acpio_size
erecovery_acpio_offset
).Uma imagem ACPIO para recuperação, incluindo os campos
recovery_acpio_size
erecovery_acpio_offset
(e nãorecovery_dtbo_size
erecovery_dtbo_offset
).
O campo header_size
contém o tamanho do cabeçalho da imagem de inicialização. Se a versão do cabeçalho da imagem de inicialização estiver definida como 1, o campo id
conterá o resumo SHA-1 para a seção recovery_[dtbo|acpio]
da imagem de inicialização, além de kernel
, ramdisk
e second sections
. Para detalhes sobre os campos
recovery_[dtbo|acpio]_size
e recovery_[dtbo|acpio]_offset
, consulte
Imagens de recuperação.
Cabeçalho da imagem de inicialização legada, versão 0
Os dispositivos lançados antes do Android 9 com o cabeçalho da imagem de inicialização legado usam a versão 0 do cabeçalho da imagem de inicialização.
struct boot_img_hdr
{
uint8_t magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
uint32_t unused;
uint32_t os_version;
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
uint8_t cmdline[BOOT_ARGS_SIZE];
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
};