Заголовок загрузочного образа

В Android 9 в заголовок загрузочного образа было добавлено поле версии, что позволяет обновлять заголовок, сохраняя обратную совместимость. Загрузчик должен проверить поле версии заголовка и проанализировать заголовок в соответствии с ним. Устройства, которые будут выпущены с:

  • В Android 13 можно использовать заголовок загрузки версии 3 или 4. Для устройств, поддерживающих архитектуру Generic Kernel Image (GKI), основной загрузочный образ – это версия 4, а поле os_version в заголовке загрузки должно быть нулевым. Загрузчик устройства должен получать информацию о версии из свойств Android Verified Boot (AVB).
  • В Android 12 можно использовать заголовок загрузки версии 3 или 4. Для устройств, поддерживающих архитектуру Generic Kernel Image (GKI), основным загрузочным образом является версия 4.
  • В Android 11 можно использовать заголовок загрузки версии 3. На устройствах, поддерживающих архитектуру Generic Kernel Image (GKI), эта версия должна использоваться для основного загрузочного образа.
  • В Android 10 должна использоваться версия 2 заголовка загрузки.
  • В Android 9 должна использоваться версия 1 заголовка загрузки.
  • В Android 8 и более ранних версиях используется заголовок загрузочного образа версии 0.

На всех устройствах с Android 9 или более поздней версии набор тестов поставщика (VTS) проверяет формат образа boot/recovery, чтобы убедиться, что в заголовке загрузочного образа используется правильная версия. Подробную информацию о заголовках загрузочных образов и загрузочных образов поставщиков, поддерживаемых в AOSP, можно найти на странице system/tools/mkbootimg/include/bootimg/bootimg.h.

Реализуйте управление версиями заголовка загрузочного образа

Инструмент mkbootimg принимает следующие аргументы:

Аргумент Описание
header_version Устанавливает версию заголовка загрузочного образа. Загрузочный образ с заголовком версии:
  • 1 или 2 поддерживает образ DTBO для восстановления или образ ACPIO для восстановления.
  • 3 не поддерживает образы для восстановления.
recovery_dtbo Используется для архитектур, в которых применяется DTB. Указывает путь к образу DTBO для восстановления. Необязательно для устройств A/B, которым не нужен образ для восстановления. Устройства без поддержки A/B-обновлений, на которых используется header_version:
  • 1 или 2 может указать этот путь или использовать раздел recovery_acpio, чтобы указать путь к образу ACPIO для восстановления.
  • 3 не может указать образ DTBO для восстановления.
recovery_acpio Используется для архитектур, в которых вместо DTB применяется ACPI. Указывает путь к образу ACPIO для восстановления. Необязательно для устройств с разделами A/B, которым не требуется образ для восстановления. Устройства без поддержки A/B-обновлений, на которых используется header_version:
  • 1 или 2 может указать этот путь или использовать раздел recovery_dtbo, чтобы указать путь к образу DTBO для восстановления.
  • 3 не может указать образ ACPIO для восстановления.
dtb Путь к образу DTB, который включен в образы загрузки/восстановления.
dtb_offset При добавлении к аргументу base предоставляет физический адрес загрузки для конечного дерева устройств. Например, если аргумент base имеет значение 0x10000000, а аргумент dtb_offset – 0x01000000, то в заголовке загрузочного образа в поле dtb_addr_field будет указано 0x11000000.

Устройство BoardConfig.mk использует конфигурацию BOARD_MKBOOTIMG_ARGS, чтобы добавить header version к другим аргументам mkbootimg, относящимся к плате. Пример:

BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)

Система сборки Android использует переменную BoardConfigBOARD_PREBUILT_DTBOIMAGE, чтобы задать аргумент recovery_dtbo инструмента mkbootimg при создании образа для восстановления. Подробную информацию об изменениях в Android Open Source Project (AOSP) можно найти в связанных списках изменений для управления версиями заголовков загрузочных образов.

Заголовок загрузочного образа, версия 4

В Android 12 в заголовке версии 4 загрузочного образа есть boot_signature, который можно использовать для проверки целостности ядра и RAM-диска. Проверка выполняется в VtsSecurityAvbTest и требуется для устройств с архитектурой GKI. Однако boot_signature не участвует в процессе подтвержденной загрузки на устройстве и используется только в VTS. Подробнее о конфигурации платы boot.img GKI и настройках проверки при запуске GKI…

Заголовок загрузочного образа поставщика версии 4 поддерживает несколько фрагментов RAM-диска поставщика.

Заголовок загрузочного образа версии 4 имеет следующий формат:

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 */
};

Заголовок загрузочного образа, версия 3

В Android 11 заголовок загрузочного образа обновлен до версии 3, в которой удалены следующие данные:

  • Загрузчик второго этапа. Поля second_size и second_addr больше не отображаются в заголовке загрузочного образа. На устройствах со вторым этапом загрузки загрузчик должен храниться в отдельном разделе.

  • Образ для восстановления. Требование указывать образ для восстановления было отменено, и поля recovery_dtbo_size, recovery_dtbo_offset, recovery_acpio_size и recovery_acpio_offset больше не отображаются в заголовке загрузочного образа.

    • В устройствах с разделами A/B используется схема обновления и восстановления, которая позволяет не указывать образ DTBO или ACPIO для восстановления.

    • На устройствах без A/B-обновлений, для которых нужно указать образ для восстановления (DTBO или ACPIO), следует использовать заголовок загрузочного образа версии 1 или 2.

  • Device tree blob (DTB). Таблица DTB хранится в разделе загрузки поставщика, поэтому поля dtb_size и dtb_addr больше не отображаются в заголовке загрузочного образа (но присутствуют в заголовке образа загрузки поставщика).

Устройства могут использовать заголовок загрузочного образа версии 3, чтобы соответствовать архитектуре Generic Kernel Image (GKI), которая объединяет основное ядро и перемещает модули поставщика, необходимые для загрузки, в раздел vendor_boot (то есть загрузочный образ содержит только компоненты GKI). Устройства, которые:

  • Используйте GKI (требуется ядро android-4.19 или android-5.4), но не используйте Обновления A/B могут указывать образ для восстановления, используя загрузочный образ версии 3 для загрузочного образа и загрузочный образ версии 2 для образа для восстановления.

  • Если вы не используете GKI и обновления A/B, то можете указать образ для восстановления, используя загрузочный образ версии 1 или 2 для загрузочных образов и образов для восстановления.

Заголовок загрузочного образа версии 3 имеет следующий формат:

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];
};

Заголовок загрузочного образа, версия 2

В Android 10 заголовок загрузочного образа обновлен до версии 2, в которой добавлен раздел для информации об образе DTB восстановления (размер образа и физический адрес загрузки).

Заголовок загрузочного образа версии 2 имеет следующий формат.

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 */
};

Заголовок загрузочного образа, версия 1

В Android 9 поле unused заголовка загрузочного образа преобразуется в поле версии заголовка. На устройствах с Android 9 должен использоваться заголовок загрузочного образа с версией заголовка 1 или выше (это проверяется VTS).

Версия 1 заголовка загрузочного образа имеет следующий формат.

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 */
};

На устройствах без поддержки A/B-обновлений можно указать образ наложения DTB/ACPI для восстановления, чтобы снизить вероятность сбоев при беспроводных обновлениях. (Устройства с разделами A/B не имеют этой проблемы и не нуждаются в указании наложенного изображения.) Вы можете указать образ DTBO или образ ACPIO, но не оба сразу, поскольку они используются разными архитектурами. Чтобы правильно настроить заголовок загрузочного образа, при использовании:

  • Образ DTBO для восстановления, включающий поля recovery_dtbo_size и recovery_dtbo_offset (и не включающий поля recovery_acpio_size и recovery_acpio_offset).

  • Образ ACPIO для восстановления. Включите поля recovery_acpio_size и recovery_acpio_offset (и не включайте поля recovery_dtbo_size и recovery_dtbo_offset).

Поле header_size содержит размер заголовка загрузочного образа. Если для версии заголовка загрузочного образа задано значение 1, поле id содержит дайджест SHA-1 для раздела recovery_[dtbo|acpio] загрузочного образа в дополнение к kernel, ramdisk и second sections. Подробные сведения о полях recovery_[dtbo|acpio]_size и recovery_[dtbo|acpio]_offset можно найти в статье Образы для восстановления.

Заголовок устаревшего загрузочного образа, версия 0

Устройства, выпущенные до Android 9 и использующие устаревший заголовок загрузочного образа, считаются устройствами с заголовком загрузочного образа версии 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];
};