Стандартный загрузочный раздел

В Android 12 общий образ boot, называемый общим образом ядра (GKI), содержит общий RAM-диск и ядро GKI.

На устройствах с Android 13 общий RAM-диск удален из образа boot и помещен в отдельный образ init_boot. В результате в образе boot останется только ядро GKI.

При обновлении устройств, на которых по-прежнему используется версия ядра Android 12 или более ранней версии, универсальный ramdisk остается на прежнем месте, и новый образ init_boot не требуется.

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

На устройствах, которые:

  • Не используйте отдельный раздел recovery. Все биты восстановления переносятся из общего ramdisk в ramdisk vendor_boot.

  • Используйте отдельный раздел recovery. Вносить изменения в ramdisk recovery не нужно, поскольку recoveryон является самодостаточным.

Архитектура

На следующих диаграммах показана архитектура для устройств с Android 12 и более поздними версиями. На устройствах с Android 13 есть новый образ init_boot, содержащий общий RAM-диск. На устройствах, на которых Android 12 обновляется до Android 13, используется та же архитектура, что и в Android 12.

Устройство поставляется с Android 13, без выделенного режима восстановления

Запуск/обновление устройства, GKI, нет выделенного режима восстановления

Рисунок 1. Устройства, которые выпускаются с Android 13 или обновляются до этой версии, с GKI и без выделенного раздела восстановления.

Устройства, выпущенные с Android 13, с выделенным разделом восстановления и A/B-обновлениями (выделенный виртуальный диск)

Запуск/обновление устройства, GKI, выделенный и A/B-разделы восстановления

Рисунок 2. Устройства, на которых установлена ОС Android 13 с GKI, выделенным и A/B-разделом восстановления.

Если на устройстве есть разделы recovery_a и recovery_b, используйте эту схему.

Запуск с Android 13, выделенное и не A/B-восстановление (выделенный RAM-диск)

Запуск/обновление устройства, GKI, выделенный и не A/B-раздел восстановления

Рисунок 3. Устройства, которые выпускаются с Android 13 или обновляются до этой версии, с GKI, выделенным и не-A/B режимом восстановления.

Используйте эту схему, если на устройстве есть раздел recovery без суффикса слота.

Запуск или обновление до Android 12, без специального восстановления

Запуск/обновление устройства, GKI, нет специального режима восстановления

Рисунок 4. Устройства, выпущенные с Android 12 или обновленные до этой версии, с GKI и без выделенного раздела восстановления.

Запуск или обновление до Android 12, выделенный и A/B-режим восстановления (выделенный RAM-диск)

Запуск/обновление устройства, GKI, выделенный и A/B-разделы восстановления

Рисунок 5. Устройства, на которых предустановлена или обновлена до Android 12 ОС с GKI, выделенным разделом восстановления и A/B-обновлениями.

Если на устройстве есть разделы recovery_a и recovery_b, используйте эту схему.

Запуск или обновление до Android 12, выделенное и не A/B восстановление (выделенный RAM-диск)

Запуск/обновление устройства, GKI, выделенный и не A/B-раздел восстановления

Рисунок 6. Устройства, на которых запускается или до которой обновляется Android 12, с GKI, выделенным и не-A/B восстановлением.

Используйте эту схему, если на устройстве есть раздел recovery без суффикса слота.

Переход на Android 12, recovery-as-boot (recovery-as-ramdisk)

Запуск/обновление устройства, без GKI, recovery-as-boot

Рисунок 7. Устройства, на которых выполняется обновление до Android 12, без GKI, с восстановлением при запуске.

Переход на Android 12, выделенное восстановление (выделенный ramdisk)

Запуск/обновление устройства, нет GKI, выделенное восстановление

Рисунок 8. Устройства, на которых выполняется обновление до Android 12, без GKI, с выделенным разделом восстановления.

Содержимое загрузочных образов

Загрузочные образы Android содержат следующие элементы:

  • Добавлен образ init_boot для устройств, выпущенных с Android 13.

    • Версия заголовка V4
    • Стандартный образ RAM-диска
  • Неактуальная boot фотография

    • Версия заголовка V3 или V4.
      • boot_signature – для сертификации boot.img GKI (только для версии 4). Сертифицированный GKI boot.img не подписан для проверки при запуске. Производители устройств должны подписывать встроенный файл boot.img с помощью ключа AVB, относящегося к определенному устройству.
      • Общие cmdline (GENERIC_KERNEL_CMDLINE)
      • Ядро GKI
    • Образ ramdisk
      • Включено только в изображениях boot, созданных на устройствах с Android 12 и более ранних версий
  • vendor_boot image (подробнее о загрузочных разделах поставщика…)

    • vendor_boot header
      • Для определенных устройств cmdline (BOARD_KERNEL_CMDLINE)
    • Образ виртуального диска vendor_boot
      • lib/modules
      • Ресурсы для восстановления (если нет специального восстановления)
    • dtb изображение
  • recovery изображение

    • Версия заголовка V2
      • cmdline для восстановления (если необходимо)
      • Для раздела восстановления, не относящегося к типу A/B, содержимое заголовка должно быть автономным. Подробнее об образах для восстановления… Пример:
      • cmdline не объединяется с boot и vendor_boot cmdline.
      • Заголовок указывает на DTBO для восстановления, если это необходимо.
      • Для раздела восстановления A/B содержимое можно объединить или вывести из boot и vendor_boot. Пример:
      • cmdline объединяется с boot и vendor_boot cmdline.
      • DTBO можно получить из заголовка vendor_boot.
    • recovery образ ramdisk
      • Ресурсы для восстановления
      • Для раздела восстановления, не относящегося к A/B, содержимое ramdisk должно быть автономным. Подробнее о образах восстановления… Пример:
      • lib/modules должен содержать все модули ядра, необходимые для загрузки режима восстановления.
      • Восстановительный RAM-диск должен содержать init.
      • Для раздела восстановления A/B виртуальный диск восстановления добавляется в начало общего виртуального диска и диска vendor_boot, поэтому он не должен быть отдельным. Пример:
      • lib/modules может содержать только дополнительные модули ядра, необходимые для загрузки режима восстановления, помимо модулей ядра в образе диска vendor_boot.
      • Символическая ссылка в /init может существовать, но она перекрывается двоичным файлом /init первого этапа в загрузочном образе.

Содержимое стандартного образа RAM-диска

Универсальный RAM-диск содержит следующие компоненты:

  • init
  • system/etc/ramdisk/build.prop
  • ro.PRODUCT.bootimg.* build предметов
  • Пустые каталоги для точек подключения: debug_ramdisk/, mnt/, dev/, sys/, proc/, metadata/.
  • first_stage_ramdisk/
    • Дублирование пустых каталогов для точек подключения: debug_ramdisk/, mnt/, dev/, sys/, proc/, metadata/

Интеграция загрузочного образа

Флаги сборки определяют, как создаются образы init_boot, boot, recovery и vendor_boot. Значение логической переменной должно быть строкой true или пустым (по умолчанию).

  • TARGET_NO_KERNEL. Эта переменная указывает, использует ли сборка предварительно созданный образ загрузки. Если для этой переменной задано значение true, то для переменной BOARD_PREBUILT_BOOTIMAGE укажите местоположение готового загрузочного образа (BOARD_PREBUILT_BOOTIMAGE:= device/${company}/${board}/boot.img).

  • BOARD_USES_RECOVERY_AS_BOOT. Эта переменная указывает, используется ли изображение recovery в качестве изображения boot. При использовании GKI эта переменная пуста, а ресурсы восстановления должны быть перемещены в vendor_boot.

  • BOARD_USES_GENERIC_KERNEL_IMAGE. Эта переменная указывает, что на плате используется GKI. Эта переменная не влияет на системные свойства или PRODUCT_PACKAGES.

    Это переключатель GKI на уровне платы. Все перечисленные ниже переменные ограничены этой переменной.

  • BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT. Эта переменная определяет, будут ли ресурсы восстановления электронного диска создаваться в vendor_boot.

    • Если задано значение true, ресурсы восстановления создаются только для vendor-ramdisk/, но не для recovery/root/.

    • Если поле пустое, ресурсы для восстановления создаются только для recovery/root/, а не для vendor-ramdisk/.

  • BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT. Эта переменная определяет, будут ли ключи GSI AVB создаваться для vendor_boot.

    • Если для параметра задано значение true, то при выполнении условия BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT:

      • Если задано, ключи AVB для GSI создаются в $ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/avb.

      • Если значение не задано, ключи AVB для GSI создаются в $ANDROID_PRODUCT_OUT/vendor-ramdisk/avb.

    • Если поле пустое и BOARD_RECOVERY_AS_ROOT:

      • Если задано, ключи GSI AVB создаются в $ANDROID_PRODUCT_OUT/recovery/root/first_stage_ramdisk/avb.

      • Если значение не задано, ключи AVB GSI создаются с учетом $ANDROID_PRODUCT_OUT/ramdisk/avb.

  • BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE. Эта переменная определяет, содержит ли образ recovery ядро. На устройствах с ОС Android 12 и разделом A/B recovery необходимо задать для этой переменной значение true. На устройствах с ОС Android 12, которые не поддерживают разделы A/B, необходимо задать для этой переменной значение false, чтобы образ для восстановления был автономным.

  • BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES. Эта переменная определяет, будет ли $OUT/boot*.img копироваться в IMAGES/ в целевых файлах.

    • aosp_arm64 должен присвоить этой переменной значение true.

    • Для других устройств оставьте эту переменную пустой.

  • BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE. Эта переменная определяет, будет ли генерироваться init_boot.img, и задает его размер. Если задано это значение, общий образ RAM-диска добавляется в init_boot.img вместо boot.img и требует, чтобы для связанного файла vbmeta были заданы переменные BOARD_AVB_INIT_BOOT*.

Допустимые сочетания

Компонент или переменная Обновление устройства без раздела восстановления Как обновить устройство с помощью раздела восстановления Запуск устройства без раздела восстановления Запуск устройства с разделом восстановления A/B Запуск устройства с разделом восстановления, не относящимся к типу A/B aosp_arm64
Содержит boot Да Да Да Да Да Да
Содержит init_boot (Android 13) Нет Нет Да Да Да Да
Содержит vendor_boot необязательно необязательно Да Да Да Нет
Содержит recovery Нет Да Нет Да Да Нет
BOARD_USES_RECOVERY_AS_BOOT true пусто пусто пусто пусто пусто
BOARD_USES_GENERIC_KERNEL_IMAGE пусто пусто true true true true
PRODUCT_BUILD_RECOVERY_IMAGE пусто true или пустое значение пусто true или пустое значение true или пустое значение пусто
BOARD_RECOVERYIMAGE_PARTITION_SIZE пусто > 0 пусто > 0 > 0 пусто
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT пусто пусто true пусто пусто пусто
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT пусто пусто true true true пусто
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE пусто пусто пусто true пусто пусто
BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES пусто пусто пусто пусто пусто true

На устройствах с выделенным разделом recovery можно задать для PRODUCT_BUILD_RECOVERY_IMAGE значение true или оставить его пустым. Если для таких устройств задано значение BOARD_RECOVERYIMAGE_PARTITION_SIZE, создается изображение recovery.

Как включить цепочку vbmeta для загрузки

Для образов boot и init_boot настоятельно рекомендуется использовать цепочку vbmeta, чтобы разрешить независимое обновление по воздуху. Укажите следующие данные:

BOARD_AVB_BOOT_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem
BOARD_AVB_BOOT_ALGORITHM := SHA256_RSA4096
BOARD_AVB_BOOT_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_BOOT_ROLLBACK_INDEX_LOCATION := 2

BOARD_AVB_INIT_BOOT_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_INIT_BOOT_ALGORITHM := SHA256_RSA2048
BOARD_AVB_INIT_BOOT_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_INIT_BOOT_ROLLBACK_INDEX_LOCATION := 3

Пример можно посмотреть в этом изменении.

System-as-root

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

Конфигурации продуктов

На устройствах, использующих универсальный RAM-диск, должен быть установлен список файлов, которые разрешено устанавливать на RAM-диск. Для этого в device.mk укажите следующее:

$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)

Файл generic_ramdisk.mk также предотвращает случайную установку других файлов в ramdisk (переместите такие файлы в vendor_ramdisk).

Как настроить устройства

Инструкции по настройке различаются в зависимости от того, на каком устройстве вы используете Android 12 или 13. Android 13 настраиваются так же, как и устройства с Android 12.

  • Устройства, на которых будет установлена ОС Android 12:

    • Может сохранять значение BOARD_USES_RECOVERY_AS_BOOT. В этом случае используются устаревшие конфигурации, и новые переменные сборки должны быть пустыми. Если такие устройства:

      • Установите для параметра BOARD_USES_RECOVERY_AS_BOOT значение true. Архитектура будет выглядеть так, как показано на рисунке 3.

      • Если оставить поле BOARD_USES_RECOVERY_AS_BOOT пустым, архитектура будет выглядеть так, как показано на рисунке 4.

    • Может задать для BOARD_USES_RECOVERY_AS_BOOT пустое значение. В этом случае они используют новые конфигурации. Если такие устройства:

      • Не используйте отдельный раздел recovery. Архитектура должна быть такой, как показано на рисунке 1, а для настройки устройства нужно выбрать вариант 1.

      • Используйте специальный раздел recovery. Архитектура показана на рисунке 2a или рисунке 2b, а вариант настройки устройства – Вариант 2a или Вариант 2b.

  • На устройствах с Android 12 необходимо задать для параметра BOARD_USES_RECOVERY_AS_BOOT пустое значение и использовать новые конфигурации. Если такие устройства:

Поскольку aosp_arm64 создает только GKI (а не vendor_boot или recovery), это неполная цель. Информацию о конфигурациях сборки aosp_arm64 можно найти в разделе generic_arm64.

Вариант 1. Нет отдельного раздела восстановления

На устройствах без раздела recovery в разделе boot содержится общее изображение boot. vendor_boot ramdisk содержит все ресурсы для восстановления, в том числе lib/modules (с модулями ядра поставщика). На таких устройствах конфигурация продукта наследуется от generic_ramdisk.mk.

Как задать значения BOARD

Задайте следующие значения:

BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT := true
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE :=
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true

В ramdisk vendor_boot может содержаться символическая ссылка /init на /system/bin/init и файл init_second_stage.recovery в каталоге /system/bin/init. Однако, поскольку общий виртуальный диск объединяется после виртуального диска vendor_boot, символическая ссылка /init перезаписывается. Когда устройство загружается в режиме восстановления, для поддержки второго этапа инициализации требуется двоичный файл /system/bin/init. Содержимое vendor_boot и универсальных виртуальных дисков:

  • /init (из универсального RAM-диска, созданного на основе init_first_stage)
  • /system/bin/init (от vendor_ramdisk, создано на основе init_second_stage.recovery)

Переместите файлы fstab

Переместите все файлы fstab, установленные на общий RAM-диск, в vendor_ramdisk. Пример можно посмотреть в этом изменении.

Как установить модули

Вы можете установить модули для определенных устройств, чтобы vendor_ramdisk (пропустите этот шаг, если у вас нет таких модулей).

  • Используйте вариант модуля vendor_ramdisk, если модуль устанавливается в /first_stage_ramdisk. Этот модуль должен быть доступен после того, как init переключит корневой каталог на /first_stage_ramdisk, но до того, как init переключит корневой каталог на /system. Примеры: контрольные суммы метаданных и сжатие виртуальных A/B-разделов.

  • Используйте вариант модуля recovery, если модуль устанавливается в /. Этот модуль должен быть доступен до того, как init переключит корневой каталог на /first_stage_ramdisk. Подробнее о том, как установить модули в /, можно узнать в консоли первого этапа.

Консоль первого этапа

Поскольку консоль первого этапа запускается до того, как init переключает корневой каталог на /first_stage_ramdisk, вам нужно установить вариант модулей recovery. По умолчанию оба варианта модуля устанавливаются в каталог build/make/target/product/base_vendor.mk, поэтому, если файл makefile устройства наследует данные из этого файла, вам не нужно явно устанавливать вариант recovery.

Чтобы установить модули восстановления, выполните следующие действия.

PRODUCT_PACKAGES += \
    linker.recovery \
    shell_and_utilities_recovery \

Это гарантирует, что linker, sh и toybox будут установлены в $ANDROID_PRODUCT_OUT/recovery/root/system/bin, который затем будет установлен в /system/bin в разделе vendor_ramdisk.

Чтобы добавить модули, необходимые для консоли первого этапа (например, adbd), используйте следующий код:

PRODUCT_PACKAGES += adbd.recovery

Это гарантирует, что указанные модули будут установлены в $ANDROID_PRODUCT_OUT/recovery/root/system/bin, который затем будет установлен в /system/bin в разделе vendor_ramdisk.

Контрольные суммы метаданных

Чтобы поддерживать контрольные суммы метаданных на первом этапе подключения, устройства, которые не поддерживают GKI, устанавливают вариант ramdisk следующих модулей. Чтобы добавить поддержку GKI, переместите модули в каталог $ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/system/bin:

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    resize2fs.vendor_ramdisk \
    tune2fs.vendor_ramdisk \

Пример можно посмотреть в этом списке изменений.

Сжатие виртуальных A/B-разделов

Чтобы поддерживать сжатие виртуального раздела A/B, snapuserd должен быть установлен в vendor_ramdisk. Устройство должно наследовать настройки от virtual_ab_ota/compression.mk, которое устанавливает вариант vendor_ramdisk приложения snapuserd.

Изменения в процессе загрузки

Процесс загрузки в режим восстановления или в Android не изменился, за исключением следующего:

  • Ramdisk build.prop перемещается в /second_stage_resources, чтобы второй этап init мог прочитать временную метку сборки загрузки.

Поскольку ресурсы перемещаются из обычного ramdisk в ramdisk vendor_boot, результат объединения обычного ramdisk с ramdisk vendor_boot не меняется.

Как сделать доступной утилиту e2fsck

Файлы makefile устройства могут наследовать от:

  • virtual_ab_ota/launch_with_vendor_ramdisk.mk, если устройство поддерживает виртуальные разделы A/B, но не сжатие.

  • virtual_ab_ota/compression.mk, если устройство поддерживает виртуальное сжатие A/B.

Файлы makefile продукта устанавливают $ANDROID_PRODUCT_OUT/vendor-ramdisk/first_stage_ramdisk/system/bin/e2fsck. Во время выполнения первый этап init переключает корневой каталог на /first_stage_ramdisk, а затем выполняет /system/bin/e2fsck.

Вариант 2а. Отдельный раздел для восстановления и A/B-тестирования

Используйте этот вариант для устройств с разделами A/B recovery, то есть с разделами recovery_a и recovery_b partition. К таким устройствам относятся устройства с разделами A/B и виртуальными разделами A/B, в которых можно обновлять раздел восстановления, со следующей конфигурацией:

AB_OTA_PARTITIONS += recovery

В ramdisk vendor_boot содержатся разделы ramdisk поставщика и модули ядра поставщика, в том числе:

  • Файлы fstab для определенных устройств

  • lib/modules (включая модули ядра поставщика)

Виртуальный диск recovery содержит все ресурсы для восстановления. На таких устройствах конфигурация продукта наследуется от generic_ramdisk.mk.

Как задать значения BOARD

Задайте следующие значения для устройств с разделом A/B recovery:

BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE := true
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true

Электронный диск recovery может содержать символическую ссылку /init -> /system/bin/init и init_second_stage.recovery в /system/bin/init. Однако, поскольку ramdisk boot добавляется после ramdisk recovery, символическая ссылка /init перезаписывается. Когда устройство загружается в режиме восстановления, для поддержки второго этапа инициализации требуется двоичный файл /system/bin/init.

Когда устройство загружается в recovery, содержимое recovery + vendor_boot + универсальных RAM-дисков выглядит следующим образом:

  • /init (из RAM-диска, созданного на основе init_first_stage)
  • /system/bin/init (из ramdisk recovery, созданного на основе init_second_stage.recovery и запущенного из /init)

Когда устройство загружается в Android, содержимое vendor_boot + generic ramdisks выглядит следующим образом:

  • /init (из универсального RAM-диска, созданного на основе init_first_stage)

Перенос файлов fstab

Переместите все файлы fstab, установленные на общий виртуальный диск, в vendor_ramdisk. Пример можно посмотреть в этом изменении.

Как установить модули

При необходимости установите модули для определенных устройств vendor_ramdisk (пропустите этот шаг, если у вас нет таких модулей). Init не переключает корневой каталог. Модули варианта vendor_ramdisk устанавливаются в корневой каталог vendor_ramdisk. Примеры установки модулей в vendor_ramdisk можно найти в разделах Консоль первого этапа, Контрольные суммы метаданных и Сжатие виртуальных разделов A/B.

Консоль первого этапа

Чтобы установить вариант vendor_ramdisk, используйте следующую команду:

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    shell_and_utilities_vendor_ramdisk \

Это гарантирует, что linker, sh и toybox будут установлены в $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin, который затем будет установлен в /system/bin в vendor_ramdisk.

Чтобы добавить модули, необходимые для консоли первого этапа (например, adbd), включите вариант vendor_ramdisk этих модулей, загрузив соответствующие исправления в AOSP, а затем используйте следующие команды:

PRODUCT_PACKAGES += adbd.vendor_ramdisk

Это гарантирует, что указанные модули будут установлены в $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin. Если ramdisk vendor_boot загружен в режиме восстановления, модуль также доступен в recovery. Если ramdisk vendor_boot не загружен в режиме восстановления, устройство может дополнительно установить adbd.recovery.

Контрольные суммы метаданных

Чтобы поддерживать контрольные суммы метаданных во время первого этапа монтирования, на устройствах, которые не поддерживают GKI, устанавливается вариант электронного диска для следующих модулей: Чтобы добавить поддержку GKI, переместите модули в каталог $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin:

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    resize2fs.vendor_ramdisk \
    tune2fs.vendor_ramdisk \

Пример можно посмотреть в этом списке изменений.

Виртуальное A/B-сжатие

Чтобы поддерживать сжатие Virtual A/B, необходимо установить snapuserd в vendor_ramdisk. Устройство должно наследовать настройки от объекта virtual_ab_ota/compression.mk, который устанавливает вариант vendor_ramdisk приложения snapuserd.

Изменения в процессе загрузки

Процесс загрузки Android не меняется. vendor_boot + generic ramdisk похож на существующий процесс загрузки, за исключением того, что fstab загружается из vendor_boot. Поскольку system/bin/recovery не существует, first_stage_init обрабатывает его как обычную загрузку.

При загрузке в режиме восстановления процесс загрузки меняется. Процесс восстановления + vendor_boot + универсальный RAM-диск похож на существующий процесс восстановления, но ядро загружается из образа boot, а не из образа recovery. Процесс загрузки в режиме восстановления выглядит следующим образом:

  1. Загрузчик запускается и выполняет следующие действия:

    1. Отправляет recovery + vendor_boot + общий ramdisk в /. Если производитель дублирует модули ядра в RAM-диске восстановления, добавляя их в BOARD_RECOVERY_KERNEL_MODULES, то vendor_boot не требуется.
    2. Запускает ядро из раздела boot.
  2. Ядро монтирует RAM-диск в /, а затем выполняет /init из универсального RAM-диска.

  3. На первом этапе инициализации выполняются следующие действия:

    1. Задает значения IsRecoveryMode() == true и ForceNormalBoot() == false.
    2. Загружает модули ядра поставщика из /lib/modules.
    3. Вызывает DoFirstStageMount(), но пропускает монтирование, потому что IsRecoveryMode() == true. (Устройство не освобождает виртуальный диск, поскольку / не меняется, но вызывает SetInitAvbVersionInRecovery().)
    4. Запускает второй этап инициализации из /system/bin/init с использованием виртуального диска recovery.

Как сделать доступной утилиту e2fsck

Файлы makefile устройства могут наследовать от:

  • virtual_ab_ota/launch_with_vendor_ramdisk.mk, если устройство поддерживает виртуальные разделы A/B, но не сжатие.

  • virtual_ab_ota/compression.mk, если устройство поддерживает виртуальное сжатие A/B.

Файлы makefile для продукта устанавливают $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin/e2fsck. Во время выполнения кода сначала выполняется этап init, а затем – /system/bin/e2fsck.

Вариант 2б. Выделенный раздел восстановления без поддержки A/B-обновлений

Используйте этот вариант для устройств с разделом recovery, не относящимся к типу A/B, то есть у которых есть раздел с названием recovery без суффикса слота. К таким устройствам относятся:

  • устройства без A/B-обновлений;
  • Устройства A/B и Virtual A/B, в которых раздел восстановления нельзя обновить. (Это необычно.)

В ramdisk vendor_boot содержатся разделы ramdisk поставщика и модули ядра поставщика, в том числе:

  • Файлы fstab для определенных устройств
  • lib/modules (включая модули ядра поставщика)

Изображение recovery должно быть самодостаточным. Он должен содержать все ресурсы, необходимые для загрузки режима восстановления, в том числе:

  • Образ ядра
  • Образ DTBO
  • Модули ядра в lib/modules
  • Инициализация первого этапа в виде символической ссылки /init -> /system/bin/init
  • Двоичный файл init второго этапа /system/bin/init
  • Файлы fstab для определенных устройств
  • Все остальные ресурсы для восстановления, включая двоичный файл recovery.

На таких устройствах конфигурация продукта наследуется от generic_ramdisk.mk.

Как задать значения BOARD

Задайте следующие значения для устройств, не поддерживающих разделы A/B:

BOARD_USES_RECOVERY_AS_BOOT :=
BOARD_USES_GENERIC_KERNEL_IMAGE := true
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT :=
BOARD_EXCLUDE_KERNEL_FROM_RECOVERY_IMAGE :=
BOARD_MOVE_GSI_AVB_KEYS_TO_VENDOR_BOOT := true

Электронный диск recovery должен содержать символическую ссылку /init -> /system/bin/init и init_second_stage.recovery в /system/bin/init. Когда устройство загружается в режиме восстановления, для поддержки инициализации на первом и втором этапах требуется двоичный файл /system/bin/init.

Когда устройство загружается в recovery, содержимое виртуальных дисков recovery выглядит следующим образом:

  • /init -> /system/bin/init (из электронного диска recovery)
  • /system/bin/init (из ramdisk recovery, созданного на основе init_second_stage.recovery и запущенного из /init)

Когда устройство загружается в Android, содержимое vendor_boot и общих виртуальных дисков выглядит следующим образом:

  • /init (с виртуального диска, созданного из init_first_stage)

Перенос файлов fstab

Переместите все файлы fstab, установленные на общий виртуальный диск, на виртуальные диски vendor_ramdisk и recovery. Пример можно посмотреть в этом изменении.

Как установить модули

Вы можете установить модули для конкретных устройств в vendor_ramdisk и на виртуальный диск recovery (пропустите этот шаг, если у вас нет модулей для конкретных устройств). init не переключает корневой каталог. Модули варианта vendor_ramdisk устанавливаются в корневой каталог vendor_ramdisk. Вариант recovery модулей устанавливается в корневой каталог ramdisk recovery. Примеры установки модулей в ramdisk vendor_ramdisk и recovery приведены в разделах Консоль первого этапа и Контрольные суммы метаданных.

Консоль первого этапа

Чтобы установить вариант vendor_ramdisk, используйте следующую команду:

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    shell_and_utilities_vendor_ramdisk \

Это гарантирует, что linker, sh и toybox будут установлены в $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin, который затем будет установлен в /system/bin в vendor_ramdisk.

Чтобы добавить модули, необходимые для консоли первого этапа (например, adbd), включите вариант vendor_ramdisk этих модулей, загрузив соответствующие исправления в AOSP, а затем используйте следующие команды:

PRODUCT_PACKAGES += adbd.vendor_ramdisk

Это гарантирует, что указанные модули будут установлены в $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin.

Чтобы установить вариант модулей recovery, замените vendor_ramdisk на recovery:

PRODUCT_PACKAGES += \
    linker.recovery \
    shell_and_utilities_recovery \
    adbd.recovery \

Контрольные суммы метаданных

Чтобы поддерживать контрольные суммы метаданных на первом этапе подключения, устройства, которые не поддерживают GKI, устанавливают вариант ramdisk следующих модулей. Чтобы добавить поддержку GKI, переместите модули в $ANDROID_PRODUCT_OUT/vendor-ramdisk/system/bin:

PRODUCT_PACKAGES += \
    linker.vendor_ramdisk \
    resize2fs.vendor_ramdisk \
    tune2fs.vendor_ramdisk \

Чтобы поддерживать контрольные суммы метаданных при монтировании на первом этапе восстановления, включите вариант восстановления этих модулей и установите их.

Изменения в процессе загрузки

При загрузке Android процесс загрузки не меняется. vendor_boot + generic ramdisk похож на существующий процесс загрузки, за исключением того, что fstab загружается из vendor_boot. Поскольку system/bin/recovery не существует, first_stage_init обрабатывает его как обычную загрузку.

При загрузке в режиме восстановления процесс загрузки не меняется. Образ ramdisk для восстановления загружается так же, как и при обычном восстановлении. Ядро загружается из образа recovery. Процесс загрузки в режиме восстановления выглядит следующим образом.

  1. Загрузчик запускается и выполняет следующие действия:

    1. Переносит виртуальный диск восстановления в /.
    2. Запускает ядро из раздела recovery.
  2. Ядро монтирует электронный диск в /, а затем выполняет /init – символическую ссылку на /system/bin/init с электронного диска recovery.

  3. На первом этапе инициализации выполняются следующие действия:

    1. Задает значения IsRecoveryMode() == true и ForceNormalBoot() == false.
    2. Загружает модули ядра поставщика из /lib/modules.
    3. Вызывает DoFirstStageMount(), но пропускает монтирование, потому что IsRecoveryMode() == true. (Устройство не освобождает виртуальный диск, поскольку / не меняется, но вызывает SetInitAvbVersionInRecovery().)
    4. Запускает второй этап инициализации из /system/bin/init из RAM-диска recovery.

Временные метки загрузочных образов

Ниже приведен пример файла временных меток для изображений boot:

####################################
# from generate-common-build-props
# These properties identify this partition image.
####################################
ro.product.bootimage.brand=Android
ro.product.bootimage.device=generic_arm64
ro.product.bootimage.manufacturer=unknown
ro.product.bootimage.model=AOSP on ARM64
ro.product.bootimage.name=aosp_arm64
ro.bootimage.build.date=Mon Nov 16 22:46:27 UTC 2020
ro.bootimage.build.date.utc=1605566787
ro.bootimage.build.fingerprint=Android/aosp_arm64/generic_arm64:S/MASTER/6976199:userdebug/test-keys
ro.bootimage.build.id=MASTER
ro.bootimage.build.tags=test-keys
ro.bootimage.build.type=userdebug
ro.bootimage.build.version.incremental=6976199
ro.bootimage.build.version.release=11
ro.bootimage.build.version.release_or_codename=S
ro.bootimage.build.version.sdk=30
# Auto-added by post_process_props.py
persist.sys.usb.config=none
# end of file
  • Во время сборки в общий образ RAM-диска добавляется файл system/etc/ramdisk/build.prop. Этот файл содержит информацию о временной метке сборки.

  • Во время выполнения первый этап init копирует файлы из RAM-диска в tmpfs, а затем освобождает RAM-диск, чтобы второй этап init мог прочитать этот файл и задать свойства временной метки образа boot.