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 e 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 adequadamente. Dispositivos lançados com:

  • O Android 13 pode usar a versão 3 ou 4 do cabeçalho de inicialização. Para dispositivos que oferecem 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 deve obter as informações de versão das propriedades da Inicialização verificada do Android (AVB).
  • O Android 12 pode usar a versão 3 ou 4 do cabeçalho de inicialização. Para dispositivos que oferecem 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 que oferecem 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 são considerados como usando um cabeçalho de imagem de inicialização versão 0.

Para todos os dispositivos com Android 9 ou mais recente, o Vendor Test Suite (VTS) 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 inicialização do fornecedor compatíveis, consulte system/tools/mkbootimg/include/bootimg/bootimg.h.

Implementar o controle de versões para cabeçalho de 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:
  • 1 ou 2 é compatível com uma imagem DTBO de recuperação ou uma imagem ACPIO de recuperação.
  • 3 não é compatível com imagens de recuperação.
recovery_dtbo Usado para arquiteturas que usam 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 é possível especificar uma imagem 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 DTBO de recuperação.
  • 3 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 carga física 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 mais detalhes sobre as mudanças no Android Open Source Project (AOSP), consulte as listas de mudanças associadas ao 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 oferece 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 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 verificada específico do dispositivo e é usado apenas no VTS. Consulte Configuração da placa boot.img do GKI e 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 de ramdisk do fornecedor.

A versão 4 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:

  • Carregador de inicialização de segunda etapa. Os campos second_size e second_addr não aparecem mais no cabeçalho da imagem de inicialização. Dispositivos com um carregador de inicialização de segunda etapa precisam armazenar esse carregador de inicialização em uma partição própria.

  • Imagem de recuperação. O requisito de 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ário especificar uma imagem DTBO ou ACPIO para recuperação.

    • Dispositivos não A/B que querem 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. Assim, 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 da imagem de inicialização do fornecedor.

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 da GKI. Dispositivos que:

  • Use o GKI (requer o kernel android-4.19 ou android-5.4), mas não use atualizações A/B. É possível 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 use GKI nem atualizações A/B. É possível especificar uma imagem de recuperação usando a versão 1 ou 2 da imagem de inicialização para imagens de inicialização e recuperação.

A versão 3 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 da imagem DTB de recuperação (tamanho da imagem e endereço de carga física).

A versão 2 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 lançados com o Android 9 precisam usar o cabeçalho da imagem de inicialização com a versão definida como 1 ou mais recente (isso é verificado pelo VTS).

A versão 1 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 */
};

Dispositivos não A/B podem especificar uma imagem de sobreposição DTB/ACPI para recuperação e ajudar a reduzir 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 ACPIO, mas não ambas, porque elas são usadas por arquiteturas diferentes. Para configurar o cabeçalho da imagem de inicialização corretamente, ao usar:

  • Uma imagem DTBO para recuperação. Inclua os campos recovery_dtbo_size e recovery_dtbo_offset, mas não inclua os campos recovery_acpio_size e recovery_acpio_offset.

  • Uma imagem ACPIO para recuperação. Inclua os campos recovery_acpio_size e recovery_acpio_offset, mas não inclua os campos 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 vai conter o resumo SHA-1 da 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 de imagem de inicialização legada, versão 0

Os dispositivos lançados antes do Android 9 que usam o cabeçalho legado da imagem de inicialização são considerados como usando 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];
};