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 bootloader deve verificar o campo de versão do cabeçalho e analisar o cabeçalho de acordo. Dispositivos iniciados com:
- O Android 12 pode usar a versão 3 ou 4 do cabeçalho de inicialização. Para dispositivos compatíveis com a 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 que suportam a arquitetura Generic Kernel Image (GKI) , esta versão deve ser usada para a imagem de inicialização primária.
- O Android 10 deve usar o cabeçalho de inicialização versão 2.
- O Android 9 deve usar a versão 1 do cabeçalho de inicialização.
- O Android 8 e inferior são considerados como usando um cabeçalho de imagem de inicialização versão 0.
Para todos os dispositivos com Android 9 ou superior, o Vendor Test Suite (VTS) verifica o formato da imagem de boot/recovery para garantir que o cabeçalho da imagem de inicialização use a versão correta. Para visualizar os detalhes do AOSP em todos os cabeçalhos de imagem de inicialização do fornecedor e de inicialização suportados atualmente, consulte system/tools/mkbootimg/include/bootimg/bootimg.h .
Implementando o controle de versão do cabeçalho da imagem de inicialização
A ferramenta mkbootimg aceita os seguintes argumentos.
| 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 usam DTB. Especifica o caminho para a imagem DTBO de recuperação. Opcional para dispositivos A/B, que não precisam de uma imagem de recuperação. Dispositivos não A/B usando 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 usando 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 a 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 compilação 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 obter detalhes sobre as alterações do Android Open Source Project (AOSP), revise as listas de alterações associadas para o controle de versão do cabeçalho da imagem de inicialização .
Cabeçalho da imagem de inicialização, versão 4
O Android 12 fornece um boot_signature no cabeçalho da imagem de inicialização versão 4, que pode ser usado para verificar a integridade do kernel e do ramdisk. A verificação é feita no 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 verificado específico do dispositivo e é usado apenas no VTS. Consulte a configuração da placa GKI boot.img e as configurações de inicialização verificadas pelo GKI para obter detalhes.
A versão 4 do cabeçalho da imagem de inicialização do fornecedor oferece suporte a fragmentos de disco ram de vários fornecedores.
A versão 4 da versão do cabeçalho da imagem de inicialização usa o seguinte formato.
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:
Bootloader de segundo estágio. Os campos
second_sizeesecond_addrnão aparecem mais no cabeçalho da imagem de inicialização. Dispositivos com um carregador de inicialização de segundo estágio devem armazenar esse carregador de inicialização em sua própria partição.Imagem de recuperação. O requisito para especificar uma imagem de recuperação foi preterido e os campos
recovery_dtbo_size,recovery_dtbo_offset,recovery_acpio_sizeerecovery_acpio_offsetnã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 desejam especificar uma imagem de recuperação (DTBO ou ACPIO) devem usar o cabeçalho da imagem de inicialização versão 1 ou 2.
Blob de árvore de dispositivos (DTB). O DTB é armazenado na partição de inicialização do fornecedor , portanto, os campos
dtb_sizeedtb_addrnão aparecem mais no cabeçalho da imagem de inicialização (mas estão presentes no cabeçalho da imagem de inicialização do fornecedor).
Os dispositivos podem usar o cabeçalho da imagem de inicialização versão 3 para cumprir com a arquitetura Generic Kernel Image (GKI) , que unifica o núcleo do kernel e move os módulos do fornecedor necessários para a inicialização para a partição vendor_boot (ou seja, a imagem de inicialização contém apenas componentes GKI). Dispositivos que:
Use GKI (requer o kernel android-4.19 ou android-5.4), mas não use atualizações A/B pode especificar uma imagem de recuperação usando a imagem de inicialização versão 3 para a imagem de inicialização e a imagem de inicialização versão 2 para a imagem de recuperação.
Não use GKI e não use atualizações A/B pode especificar uma imagem de recuperação usando a imagem de inicialização versão 1 ou 2 para imagens de inicialização e recuperação.
A versão 3 da versão do cabeçalho da imagem de inicialização usa o seguinte formato.
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 imagem DTB de recuperação (tamanho da imagem e endereço de carregamento físico).
A versão 2 da versão do cabeçalho da imagem de inicialização usa o seguinte formato.
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 iniciados com o Android 9 devem usar o cabeçalho da imagem de inicialização com a versão do cabeçalho definida como 1 ou superior (isso é verificado pelo VTS).
A versão 1 da versão 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 */
};
Dispositivos não A/B podem especificar uma imagem de sobreposição DTB/ACPI para recuperação para ajudar a mitigar falhas de atualização over-the-air (OTA). (Os dispositivos A/B não têm esse problema e não precisam especificar uma imagem de sobreposição.) Você pode especificar uma imagem DTBO ou uma imagem ACPIO, mas não ambas (porque elas são usadas por diferentes arquiteturas). Para configurar o cabeçalho da imagem de inicialização corretamente, ao usar:
Uma imagem DTBO para recuperação, inclua os campos
recovery_dtbo_sizeerecovery_dtbo_offset(e não inclua os camposrecovery_acpio_sizeerecovery_acpio_offset).Uma imagem ACPIO para recuperação, inclua os campos
recovery_acpio_sizeerecovery_acpio_offset(e não inclua os camposrecovery_dtbo_sizeerecovery_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 for 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 das seções kernel , ramdisk e second sections . Para obter detalhes sobre os recovery_[dtbo|acpio]_size e recovery_[dtbo|acpio]_offset , consulte Imagens de recuperação .
Cabeçalho de imagem de inicialização herdado, versão 0
Dispositivos lançados antes do Android 9 usando o cabeçalho de imagem de inicialização herdado são considerados como usando um cabeçalho de imagem de inicialização versão 0.
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];
};