В Android 11 появилась концепция универсального образа ядра (GKI). Чтобы обеспечить загрузку произвольного устройства с помощью GKI, устройства Android 11 могут использовать заголовок загрузочного образа версии 3. В версии 3 вся информация, специфичная для поставщика, выносится из boot
раздела и перемещается в новый vendor_boot
. Устройство ARM64, запускаемое с Android 11 на ядре Linux 5.4, должно поддерживать vendor_boot
и обновленный формат boot
раздела, чтобы пройти тестирование с помощью GKI.
Устройства Android 12 могут использовать заголовок загрузочного образа версии 4, который поддерживает включение нескольких виртуальных дисков поставщиков в vendor_boot
. Несколько фрагментов виртуального диска поставщика объединяются один за другим в разделе виртуального диска поставщика. Таблица виртуального диска поставщика используется для описания структуры раздела виртуального диска поставщика и метаданных каждого фрагмента виртуального диска поставщика.
Структура разделов
Загрузочный раздел поставщика имеет класс A/B с виртуальным A/B и защищен Android Verified Boot.
Версия 3
Раздел состоит из заголовка, виртуального диска поставщика и объекта дерева устройств (DTB).
Раздел | Количество страниц |
---|---|
Загрузочный заголовок поставщика (n страниц) | n = (2112 + page_size - 1) / page_size |
RAM-диск поставщика (о страниц) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (стр.) | p = (dtb_size + page_size - 1) / page_size |
Версия 4
Раздел состоит из заголовка, раздела виртуального диска поставщика (состоящего из всех объединенных фрагментов виртуального диска поставщика), объекта дерева устройств (DTB) и таблицы виртуального диска поставщика.
Раздел | Количество страниц |
---|---|
Загрузочный заголовок поставщика (n страниц) | n = (2128 + page_size - 1) / page_size |
Фрагменты виртуального диска поставщика (o страниц) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (стр.) | p = (dtb_size + page_size - 1) / page_size |
Таблица виртуального диска поставщика (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_type
обозначает тип виртуального диска, возможные значения:-
VENDOR_RAMDISK_TYPE_NONE
указывает, что значение не указано. - RAM-диски
VENDOR_RAMDISK_TYPE_PLATFORM
содержат биты, специфичные для платформы. Загрузчик всегда должен загружать их в память. - RAM-диски
VENDOR_RAMDISK_TYPE_RECOVERY
содержат ресурсы восстановления. Загрузчик должен загрузить их в память при загрузке в рекавери. - RAM-диски
VENDOR_RAMDISK_TYPE_DLKM
содержат динамически загружаемые модули ядра.
-
-
ramdisk_name
— уникальное имя виртуального диска. -
board_id
— это вектор идентификаторов оборудования, определенных поставщиком.
Поддержка загрузчика
Поскольку загрузочный раздел поставщика содержит информацию (например, размер флэш-страницы, ядро, адреса загрузки виртуального диска, сам DTB), которая ранее существовала в загрузочном разделе, загрузчик должен получить доступ как к загрузочному разделу, так и к загрузочному разделу поставщика, чтобы иметь достаточно данных для завершения загрузки. .
Загрузчик должен загрузить общий виртуальный диск в память сразу после виртуального диска поставщика (форматы CPIO, Gzip и lz4 поддерживают этот тип конкатенации). Не выравнивайте по страницам общий образ виртуального диска и не вводите какое-либо другое пространство между ним и концом виртуального диска поставщика в памяти. После распаковки ядра оно извлекает объединенный файл в initramfs
, в результате чего получается файловая структура, представляющая собой общий виртуальный диск, наложенный на файловую структуру виртуального диска поставщика.
Поскольку общий виртуальный диск и виртуальный диск поставщика объединяются, они должны быть в одном формате. Загрузочный образ GKI использует общий виртуальный диск, сжатый lz4, поэтому устройство, совместимое с GKI, должно использовать виртуальный диск поставщика, сжатый lz4. Конфигурация для этого показана ниже.
Требования к загрузчику для поддержки bootconfig описаны в разделе «Реализация Bootconfig» .
Несколько виртуальных дисков поставщиков (версия 4)
При использовании заголовка загрузочного образа версии 4 загрузчик может выбрать подмножество или все виртуальные диски поставщика для загрузки в качестве initramfs
во время загрузки. Таблица виртуального диска поставщика содержит метаданные каждого виртуального диска и может помочь загрузчику решить, какие виртуальные диски загружать. Загрузчик может определить порядок загрузки виртуальных дисков выбранного поставщика, при условии, что общий виртуальный диск загружается последним.
Например, загрузчик может не загружать виртуальные диски поставщика типа VENDOR_RAMDISK_TYPE_RECOVERY
во время обычной загрузки для экономии ресурсов, поэтому в память загружаются только виртуальные диски поставщика типа VENDOR_RAMDISK_TYPE_PLATFORM
и VENDOR_RAMDISK_TYPE_DLKM
. С другой стороны, виртуальные диски производителя типа VENDOR_RAMDISK_TYPE_PLATFORM
, VENDOR_RAMDISK_TYPE_RECOVERY
и VENDOR_RAMDISK_TYPE_DLKM
загружаются в память при загрузке в режиме восстановления.
В качестве альтернативы загрузчик может игнорировать таблицу виртуального диска поставщика и загружать весь раздел виртуального диска поставщика. Это имеет тот же эффект, что и загрузка всех фрагментов виртуального диска поставщика в vendor_boot
.
Создайте поддержку
Чтобы реализовать поддержку загрузки устройства поставщиком:
Установите для
BOARD_BOOT_HEADER_VERSION
значение3
или выше.Установите для
BOARD_RAMDISK_USE_LZ4
значениеtrue
, если ваше устройство совместимо с GKI или если оно иным образом использует общий виртуальный диск, сжатый 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)
.
Чтобы включить несколько виртуальных дисков поставщика 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
будет содержать два фрагмента виртуального диска поставщика. Первый — это виртуальный диск «по умолчанию», который содержит каталог baz
DLKM и остальные файлы в $(TARGET_VENDOR_RAMDISK_OUT)
. Второй — это виртуальный диск dlkm_foobar
, который содержит каталоги DLKM foo
и bar
, а --ramdisk_type
по умолчанию имеет значение DLKM
.