Загрузочные разделы поставщика

Android 11 представил концепцию Generic Kernel Image (GKI). Чтобы включить легко загружая произвольное устройство с ГКА, Android 11 устройства может использовать изображение заголовка загрузки версию 3. В 3 -е версии, вся информация конкретного производителя раскладывается из boot раздела и переехала в новое vendor_boot раздела. ARM64 устройство запуск с Android 11 на Linux ядре 5.4 должен поддерживать vendor_boot раздел и обновленный boot формат раздела , чтобы пройти тестирование с ГКО.

Android 12 устройство может использовать заголовок изображения загрузки версию 4, которая поддерживает в том числе нескольких загрузочных дисков поставщика в vendor_boot раздела. Множественные фрагменты виртуального диска поставщика объединяются один за другим в разделе виртуального диска поставщика. Таблица производителей ramdisk используется для описания структуры раздела ramdisk поставщика и метаданных каждого фрагмента ramdisk поставщика.

Структура перегородки

Загрузочный раздел поставщика - A / B с виртуальным A / B и защищен Android Verified Boot.

Версия 3

Раздел состоит из заголовка, виртуального диска поставщика и большого двоичного объекта дерева устройств (DTB).

Раздел Число страниц
Заголовок загрузки поставщика (n страниц) n = (2112 + page_size - 1) / page_size
RAM-диск поставщика (o стр.) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (p стр.) p = (dtb_size + page_size - 1) / page_size

Версия 4

Раздел состоит из заголовка, раздела виртуального диска поставщика (состоящего из всех связанных фрагментов виртуального диска поставщика), большого двоичного объекта дерева устройств (DTB) и таблицы виртуального диска поставщика.

Раздел Число страниц
Заголовок загрузки поставщика (n страниц) n = (2128 + page_size - 1) / page_size
Фрагменты ramdisk от поставщика (o стр.) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (p стр.) p = (dtb_size + page_size - 1) / page_size
Таблица поставщиков RAMDisk (q страниц) q = (vendor_ramdisk_table_size + page_size - 1) / page_size
Bootconfig (r страницы) r = (bootconfig_size + page_size - 1) / page_size

Заголовок загрузки поставщика

Содержимое заголовка раздела загрузки поставщика состоит в основном из данных , который был переселены туда из заголовка загрузочного образа . Он также содержит информацию о виртуальном диске поставщика.

Версия 3

struct vendor_boot_img_hdr_v3
{
#define VENDOR_BOOT_MAGIC_SIZE 8
    uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
    uint32_t header_version;
    uint32_t page_size;           /* flash page size we assume */

    uint32_t kernel_addr;         /* physical load addr */
    uint32_t ramdisk_addr;        /* physical load addr */

    uint32_t vendor_ramdisk_size; /* size in bytes */

#define VENDOR_BOOT_ARGS_SIZE 2048
    uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];

    uint32_t tags_addr;           /* physical addr for kernel tags */

#define VENDOR_BOOT_NAME_SIZE 16
    uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;         /* size of vendor boot image header in
                                   * bytes */
    uint32_t dtb_size;            /* size of dtb image */
    uint64_t dtb_addr;            /* physical load address */

};

Версия 4

struct vendor_boot_img_hdr_v4
{
#define VENDOR_BOOT_MAGIC_SIZE 8
    uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
    uint32_t header_version;
    uint32_t page_size;           /* flash page size we assume */

    uint32_t kernel_addr;         /* physical load addr */
    uint32_t ramdisk_addr;        /* physical load addr */

    uint32_t vendor_ramdisk_size; /* size in bytes */

#define VENDOR_BOOT_ARGS_SIZE 2048
    uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];

    uint32_t tags_addr;           /* physical addr for kernel tags */

#define VENDOR_BOOT_NAME_SIZE 16
    uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;         /* size of vendor boot image header in
                                   * bytes */
    uint32_t dtb_size;            /* size of dtb image */
    uint64_t dtb_addr;            /* physical load address */

    uint32_t vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
    uint32_t bootconfig_size; /* size in bytes for the bootconfig section */
};

#define VENDOR_RAMDISK_TYPE_NONE 0
#define VENDOR_RAMDISK_TYPE_PLATFORM 1
#define VENDOR_RAMDISK_TYPE_RECOVERY 2
#define VENDOR_RAMDISK_TYPE_DLKM 3

struct vendor_ramdisk_table_entry_v4
{
    uint32_t ramdisk_size; /* size in bytes for the ramdisk image */
    uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
    uint32_t ramdisk_type; /* type of the ramdisk */
#define VENDOR_RAMDISK_NAME_SIZE 32
    uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */

#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
    // Hardware identifiers describing the board, soc or platform which this
    // ramdisk is intended to be loaded on.
    uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE];
};
  • vendor_ramdisk_size это общий размер всех фрагментов поставщика Ramdisk.
  • ramdisk_type обозначает тип псевдодиска, возможные значения:
    • VENDOR_RAMDISK_TYPE_NONE указывает значение не определено.
    • VENDOR_RAMDISK_TYPE_PLATFORM RAMдиск , содержат платформы конкретные биты. Загрузчик всегда должен загружать их в память.
    • VENDOR_RAMDISK_TYPE_RECOVERY RAMдиск , содержат ресурсы для восстановления. Загрузчик должен загрузить их в память при загрузке в режим восстановления.
    • VENDOR_RAMDISK_TYPE_DLKM RAMдиск , содержат динамические загружаемые модули ядра.
  • ramdisk_name это уникальное имя псевдодиска.
  • board_id является вектором поставщика определяется аппаратных идентификаторов.

Поддержка загрузчика

Поскольку загрузочный раздел поставщика содержит информацию (например, размер флеш-страницы, ядро, адреса загрузки RAM-диска, сам DTB), которая ранее существовала в загрузочном разделе, загрузчик должен иметь доступ как к загрузочному разделу, так и к загрузочному разделу поставщика, чтобы иметь достаточно данных для завершения загрузки. .

Загрузчик должен загрузить общий виртуальный диск в память сразу после псевдодиска поставщика (в CPIO, GZIP и форматы LZ4 поддерживают этот тип конкатенации). Не выравнивайте по страницам общий образ виртуального диска и не вводите любое другое пространство между ним и концом виртуального диска поставщика в памяти. После распаковывают ядра, он извлекает каскадный файл в initramfs , который приводит в файловой структуре , что это общий виртуальный диск наложенный на структуру поставщик электронного диска файла.

Поскольку общий RAM-диск и RAM-диск поставщика объединяются, они должны быть в одном формате. Загрузочный образ GKI использует общий ramdisk, сжатый lz4, поэтому устройство, совместимое с GKI, должно использовать сжатый lz4 ramdisk поставщика. Конфигурация для этого показана ниже.

Требования загрузчика для поддержки bootconfig объясняются на Исполнительном Bootconfig странице.

RAM-диски от нескольких поставщиков (версия 4)

При загрузке заголовок изображения версии 4, загрузчик может выбрать либо подмножество или все поставщика загрузочных дисков до нагрузки , как и initramfs во время загрузки. Таблица RAM-диска поставщика содержит метаданные каждого RAM-диска и может помочь загрузчику решить, какие RAM-диски загружать. Загрузчик может определять порядок загрузки RAM-дисков выбранного поставщика, если общий RAM-диск загружается последним.

Например, загрузчик может опустить загрузки поставщика RAMдиск , типа VENDOR_RAMDISK_TYPE_RECOVERY во время нормальной загрузки для экономии ресурсов, так что только производитель RAMдиск , типа VENDOR_RAMDISK_TYPE_PLATFORM и VENDOR_RAMDISK_TYPE_DLKM загружается в память. С другой стороны, поставщик RAMдиск , типа VENDOR_RAMDISK_TYPE_PLATFORM , VENDOR_RAMDISK_TYPE_RECOVERY и VENDOR_RAMDISK_TYPE_DLKM загружаются в память при загрузке в режим восстановления.

В качестве альтернативы загрузчик может игнорировать таблицу виртуального диска поставщика и загрузить весь раздел виртуального диска поставщика. Это имеет тот же эффект, что делает загрузку всех фрагментов поставщика Ramdisk в vendor_boot раздела.

Поддержка сборки

Чтобы реализовать поддержку загрузки от поставщика для устройства:

  • Набор BOARD_BOOT_HEADER_VERSION до 3 или больше.

  • Набор BOARD_RAMDISK_USE_LZ4 к true , если устройство ГКО-совместимое, или если он в противном случае использует LZ4 сжатые общий псевдодиск.

  • Набор BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE до нужного размера для вашего устройства, с учетом модулей ядра , которые должны пойти на поставщик псевдодиска.

  • Обновление AB_OTA_PARTITIONS включать vendor_boot и любые поставщика конкретные списки OTA разделов на устройстве.

  • Скопируйте устройство fstab в /first_stage_ramdisk в vendor_boot раздела, а не boot раздела. Например, $(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM) .

Чтобы включить несколько поставщиков RAMдиск , в vendor_boot :

  • Установите BOARD_BOOT_HEADER_VERSION на 4 .
  • Набор BOARD_VENDOR_RAMDISK_FRAGMENTS к списку имен фрагментов электронного диска логического поставщика должны быть включены в vendor_boot .

  • Для добавления поставщика псевдодиск скомпилированного, набор BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT на путь прекомпилированного файла.

  • Для добавления поставщика псевдодиск DLKM, набор BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS в список модулей ядра каталогов , которые будут включены.

  • Набор BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS для mkbootimg аргументы. Это --board_id[0-15] и --ramdisk_type аргументы для фрагмента поставщика электронного диска. Для DLKM поставщика псевдодиска по умолчанию --ramdisk_type будет DLKM , если это не указано иначе.

Строить ресурсы для восстановления в качестве автономного recovery псевдодиска в vendor_boot :

  • Установите BOARD_BOOT_HEADER_VERSION на 4 .
  • Набор BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT к true .
  • Набор BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT к true .
  • Это добавляет фрагмент поставщик электронного диска , чей ramdisk_name является recovery и ramdisk_type является VENDOR_RAMDISK_TYPE_RECOVERY . Затем виртуальный диск содержит все файлы восстановления, которые являются файлы , установленные в $(TARGET_RECOVERY_ROOT_OUT) .

mkbootimg аргументы

Аргумент Описание
--ramdisk_type Тип псевдодиска, может быть одним из NONE , PLATFORM , RECOVERY или DLKM .
--board_id[0-15] Укажите board_id вектор, по умолчанию 0 .

Ниже приведен пример конфигурации:

BOARD_KERNEL_MODULE_DIRS := foo bar baz
BOARD_BOOT_HEADER_VERSION := 4
BOARD_VENDOR_RAMDISK_FRAGMENTS := dlkm_foobar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.KERNEL_MODULE_DIRS := foo bar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.MKBOOTIMG_ARGS := --board_id0 0xF00BA5 --board_id1 0xC0FFEE

В результате vendor_boot будет содержать два фрагмента поставщика Ramdisk. Первый из них является « по умолчанию» виртуальный диск, который содержит каталог DLKM baz и остальные файлы в $(TARGET_VENDOR_RAMDISK_OUT) . Второй является dlkm_foobar виртуального диска, который содержит DLKM каталоги foo и bar , и --ramdisk_type по умолчанию в DLKM .