Cabeçalho da imagem de inicialização

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:
  • 1 ou 2 é compatível com uma imagem de DTBO de recuperação ou uma imagem ACPIO de recuperação.
  • O número 3 não é compatível com imagens de recuperação.
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:
  • 1 ou 2 podem especificar esse caminho ou usar a seção recovery_acpio para especificar um caminho para uma imagem ACPIO de recuperação.
  • 3 não podem especificar uma imagem de DTBO de recuperação.
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:
  • 1 ou 2 podem especificar esse caminho ou usar a seção recovery_dtbo para especificar um caminho para uma imagem de DTBO de recuperação.
  • No segundo, não é possível especificar uma imagem ACPIO de recuperação.
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 e second_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 e recovery_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 e dtb_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 e recovery_dtbo_offset (e não inclua os campos recovery_acpio_size e recovery_acpio_offset).

  • Uma imagem ACPIO para recuperação, incluindo os campos recovery_acpio_size e recovery_acpio_offset (e não recovery_dtbo_size e recovery_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];
};