Переместить fastboot в пространство пользователя

Fastboot — это название модуля и режима загрузчика. Android 10 и выше поддерживает разделы с изменяемым размером, перемещая реализацию fastboot из загрузчика в пространство пользователя. Это перемещение позволяет переместить код прошивки в обслуживаемое и тестируемое общее расположение, в котором только специфичные для поставщика части fastboot реализованы с помощью уровня абстракции оборудования (HAL). Кроме того, Android 12 и выше поддерживает прошивку ramdisk с помощью добавленной команды fastboot.

Унифицировать быструю загрузку и восстановление

Поскольку fastboot и recovery в пользовательском пространстве похожи, вы можете объединить их в один раздел или двоичный файл. Это дает такие преимущества, как использование меньшего пространства, меньшее количество разделов в целом и совместное использование fastboot и recovery своих ядер и библиотек.

Fastbootd — это имя демона и режима пользовательского пространства. Для поддержки fastbootd загрузчик должен реализовать новую команду блока управления загрузкой (BCB) boot-fastboot . Чтобы войти в режим fastbootd , загрузчик записывает boot-fastboot в поле команды сообщения BCB и оставляет поле recovery BCB неизменным (чтобы разрешить перезапуск любых прерванных задач восстановления). Поля status , stage и reserved также остаются неизменными. Загрузчик загружает и загружает образ восстановления, увидев boot-fastboot в поле команды BCB. Затем восстановление анализирует сообщение BCB и переключается в режим fastbootd .

Команды ADB

В этом разделе описывается команда adb для интеграции fastbootd . Команда имеет разные результаты в зависимости от того, выполняется ли она системой или восстановлением.

Команда Описание
reboot fastboot
  • Перезагружается в fastbootd (систему).
  • Вход в fastbootd напрямую без перезагрузки (восстановления).

Команды быстрой загрузки

В этом разделе описываются команды fastboot для интеграции fastbootd , включая новые команды для прошивки и управления логическими разделами. Некоторые команды имеют разные результаты в зависимости от того, были ли они выполнены загрузчиком или fastbootd .

Команда Описание
reboot recovery
  • Перезагружается в режим восстановления (загрузчик).
  • Вход в режим восстановления напрямую, без перезагрузки ( fastbootd ).
reboot fastboot Перезагружается в fastbootd .
getvar is-userspace
  • Возвращает yes ( fastbootd ).
  • Возвращает no (загрузчик).
getvar is-logical: <partition> Возвращает yes если данный раздел является логическим разделом, no в противном случае. Логические разделы поддерживают все команды, перечисленные ниже.
getvar super-partition-name Возвращает имя суперраздела. Имя включает текущий суффикс слота, если суперраздел является разделом A/B (обычно это не так).
create-logical-partition <partition> <size> Создает логический раздел с указанным именем и размером. Имя не должно уже существовать как логический раздел.
delete-logical-partition <partition> Удаляет указанный логический раздел (фактически стирает раздел).
resize-logical-partition <partition> <size> Изменяет размер логического раздела до нового размера без изменения его содержимого. Не удается, если недостаточно места для выполнения изменения размера.
flash <partition> [ <filename> ] Записывает файл на флэш-раздел. Устройство должно быть в разблокированном состоянии.
erase <partition> Стирает раздел (не обязательно для безопасного стирания). Устройство должно быть в разблокированном состоянии.
getvar <variable> | all Отображает переменную загрузчика или все переменные. Если переменная не существует, возвращает ошибку.
set_active <slot>

Устанавливает указанный слот загрузки A/B как active . При следующей попытке загрузки система загрузится из указанного слота.

Для поддержки A/B слоты представляют собой дублированные наборы разделов, с которых можно загружаться независимо. Слоты называются a , b и т. д. и различаются добавлением суффиксов _a , _b и т. д. к имени раздела.

reboot Перезагружает устройство в обычном режиме.
reboot-bootloader (или reboot bootloader ) Перезагружает устройство в режим загрузчика.
fastboot fetch vendor_boot <out.img>

Используйте в Android 12 и выше для поддержки прошивки RAM-дисков поставщика.

Получает весь размер раздела и размер куска. Получает данные для каждого куска, затем сшивает данные вместе в <out.img>

Подробную информацию см. в разделе fastboot fetch vendor_boot <out.img> .

fastboot flash vendor_boot:default <vendor-ramdisk.img>

Используйте в Android 12 и выше для поддержки прошивки RAM-дисков поставщика.

Это специальный вариант команды flash. Она выполняет функцию fetch vendor_boot image, как если бы была вызвана fastboot fetch . Новый образ vendor_boot который она прошивает, зависит от того, является ли версия заголовка загрузки версией 3 или версией 4.

Подробную информацию см. в разделе fastboot flash vendor_boot:default <vendor-ramdisk.img> .

fastboot flash vendor_boot: <foo> <vendor-ramdisk.img> Используйте в Android 12 и выше для поддержки прошивки RAM-дисков поставщика.

Извлекает образ vendor_boot . Возвращает ошибку, если заголовок загрузки vendor имеет версию 3. Если это версия 4, он находит правильный фрагмент ramdisk vendor (если доступен). Он заменяет его указанным образом, пересчитывает размеры и смещения и прошивает новый vendor_boot image .

Подробную информацию см. в fastboot flash vendor_boot: <foo> <vendor-ramdisk.img>

Fastboot и загрузчик

Загрузчик прошивает разделы bootloader , radio и boot/recovery , после чего устройство загружается в fastboot (userspace) и прошивает все остальные разделы. Загрузчик должен поддерживать следующие команды.

Команда Описание
download Загружает образ во флэш.
flash recovery <image> / flash boot <image> / flash bootloader <image> / Перепрошивка раздела recovery/boot и загрузчика.
reboot Перезагружает устройство.
reboot fastboot Перезагружается в режиме быстрой загрузки.
reboot recovery Перезагружается в режим восстановления.
getvar Получает переменную загрузчика, необходимую для прошивки образа восстановления/загрузки (например, current-slot и max-download-size ).
oem <command> Команда определена OEM.

Динамические разделы

Загрузчик не должен допускать перепрошивку или стирание динамических разделов и должен возвращать ошибку при попытке выполнения этих операций. Для модернизированных устройств с динамическими разделами инструмент fastboot (и загрузчик) поддерживает принудительный режим для прямой прошивки динамического раздела в режиме загрузчика. Например, если system является динамическим разделом на модернизированном устройстве, использование команды fastboot --force flash system позволяет загрузчику (вместо fastbootd ) перепрошивать раздел.

Зарядка в выключенном режиме

Если устройство поддерживает зарядку в выключенном режиме или иным образом автоматически загружается в специальный режим при подаче питания, реализация команды fastboot oem off-mode-charge 0 должна обойти эти специальные режимы, чтобы устройство загружалось так, как если бы пользователь нажал кнопку питания.

Быстрая загрузка OEM HAL

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

Определение fastboot HAL следующее:

import IFastbootLogger;

/**
 * IFastboot interface implements vendor specific fastboot commands.
 */
interface IFastboot {
    /**
     * Returns a bool indicating whether the bootloader is enforcing verified
     * boot.
     *
     * @return verifiedBootState True if the bootloader is enforcing verified
     * boot and False otherwise.
     */
    isVerifiedBootEnabled() generates (bool verifiedBootState);

    /**
     * Returns a bool indicating the off-mode-charge setting. If off-mode
     * charging is enabled, the device autoboots into a special mode when
     * power is applied.
     *
     * @return offModeChargeState True if the setting is enabled and False if
     * not.
     */
    isOffModeChargeEnabled() generates (bool offModeChargeState);

    /**
     * Returns the minimum battery voltage required for flashing in mV.
     *
     * @return batteryVoltage Minimum battery voltage (in mV) required for
     * flashing to be successful.
     */
    getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage);

    /**
     * Returns the file system type of the partition. This is only required for
     * physical partitions that need to be wiped and reformatted.
     *
     * @return type Can be ext4, f2fs or raw.
     * @return result SUCCESS if the operation is successful,
     * FAILURE_UNKNOWN if the partition is invalid or does not require
     * reformatting.
     */
    getPartitionType(string partitionName) generates (FileSystemType type, Result result);

    /**
     * Executes a fastboot OEM command.
     *
     * @param oemCmd The oem command that is passed to the fastboot HAL.
     * @response result Returns the status SUCCESS if the operation is
     * successful,
     * INVALID_ARGUMENT for bad arguments,
     * FAILURE_UNKNOWN for an invalid/unsupported command.
     */
    doOemCommand(string oemCmd) generates (Result result);

};

Включить fastbootd

Чтобы включить fastbootd на устройстве:

  1. Добавьте fastbootd в PRODUCT_PACKAGES в device.mk : PRODUCT_PACKAGES += fastbootd .

  2. Убедитесь, что HAL быстрой загрузки, HAL управления загрузкой и HAL работоспособности упакованы как часть образа восстановления.

  3. Добавьте любые разрешения SEPolicy, специфичные для устройства, требуемые fastbootd . Например, fastbootd требует права записи в раздел, специфичный для устройства, чтобы прошить этот раздел. Кроме того, реализация HAL fastboot может также потребовать разрешения, специфичные для устройства.

Для проверки быстрой загрузки пользовательского пространства запустите Vendor Test Suite (VTS) .

RAM-диски от поставщика флэш-памяти

Android 12 и выше поддерживает прошивку ramdisks с добавленной командой fastboot, которая извлекает полный образ vendor_boot из устройства. Команда предлагает инструменту fastboot на стороне хоста прочитать заголовок загрузки поставщика, переименовать и прошить новый образ.

Чтобы извлечь полный образ vendor_boot , команда fetch:vendor_boot была добавлена ​​как в протокол fastboot, так и в реализацию протокола fastbootd в Android 12. Обратите внимание, что fastbootd реализует это, но сам загрузчик может и не реализовать. OEM-производители могут добавить команду fetch:vendor_boot в свою реализацию протокола загрузчиком. Однако, если команда не распознается в режиме загрузчика, то прошивка отдельных ramdisk-ов вендора в режиме загрузчика не поддерживается поставщиком.

Изменения загрузчика

Команды getvar:max-fetch-size и fetch:name реализованы в fastbootd . Для поддержки прошивки RAM-дисков в загрузчике необходимо реализовать эти две команды.

Изменения Fastbootd

getvar:max-fetch-size похож на max-download-size . Он указывает максимальный размер, который устройство может отправить в одном ответе DATA. Драйвер не должен извлекать размер больше этого значения.

fetch:name[:offset[:size]] выполняет серию проверок на устройстве. Если все нижеперечисленное верно, команда fetch:name[:offset[:size]] возвращает данные:

  • На устройстве запущена отладочная сборка.
  • Устройство разблокировано (состояние загрузки оранжевое).
  • Извлеченное имя раздела — vendor_boot .
  • Значение size находится в диапазоне 0 < size <= max-fetch-size .

Когда они проверены, fetch:name[:offset[:size]] возвращает размер раздела и смещение. Обратите внимание на следующее:

  • fetch:name эквивалентно fetch:name:0 , что эквивалентно fetch:name:0:partition_size .
  • fetch:name:offset эквивалентно fetch:name:offset:(partition_size - offset)

Поэтому fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset) .

Если offset или partition_size (или оба) не указаны, используются значения по умолчанию, где offset равен 0, а size — вычисленному значению partition_size - offset .

  • Смещение указано, размер не указан: size = partition_size - offset
  • Ни один из них не указан: для обоих используются значения по умолчанию, size = partition_size - 0.

Например, fetch:foo извлекает весь раздел foo со смещением 0.

Изменения в драйверах

Команды были добавлены в инструмент fastboot для реализации изменений драйверов. Каждая из них связана с ее полным определением в таблице команд Fastboot .

  • fastboot fetch vendor_boot out.img

    • Вызывает getvar max-fetch-size для определения размера фрагмента.
    • Вызывает getvar partition-size:vendor_boot[_a] для определения размера всего раздела.
    • Вызывает fastboot fetch vendor_boot[_a]:offset:size для каждого фрагмента. (Размер фрагмента больше размера vendor_boot , поэтому обычно имеется только один фрагмент.)
    • Сшивает данные вместе в out.img .
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    Это специальный вариант команды flash. Он извлекает образ vendor_boot , как если бы была вызвана fastboot fetch .

    • Если загрузчик поставщика имеет версию заголовка 3 , он выполняет следующие действия:
      • Заменяет виртуальный диск поставщика указанным образом.
      • Запускает новый образ vendor_boot .
    • Если загрузочный заголовок поставщика имеет версию 4 , он выполняет следующие действия:
      • Заменяет весь ramdisk поставщика указанным образом, так что указанный образ становится единственным фрагментом ramdisk поставщика в образе vendor_boot .
      • Пересчитывает размер и смещение в таблице RAM-диска поставщика.
      • Запускает новый образ vendor_boot .
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    Извлекает vendor_boot image , как если бы была вызвана fastboot fetch .

    • Если загрузочный заголовок поставщика имеет версию 3, возвращается ошибка.
    • Если загрузочный заголовок поставщика имеет версию 4, он выполняет следующие действия:

      • Находит фрагмент ramdisk поставщика с именем ramdisk_<var>&lt;foo></var> . Если не найден или есть несколько совпадений, возвращает ошибку.
      • Заменяет фрагмент ramdisk поставщика указанным образом.
      • Пересчитывает каждый размер и смещение в таблице RAM-диска поставщика.
      • Запускает новый образ vendor_boot .
    • Если <foo> не указан, будет предпринята попытка найти ramdisk_ .

mkbootimg

Имя default зарезервировано для именования фрагментов ramdisk поставщика в Android 12 и выше. Хотя семантика fastboot flash vendor_boot:default остается прежней, вы не должны называть свои фрагменты ramdisk как default .

Изменения SELinux

В fastbootd.te внесены изменения для поддержки перепрошивки RAM-дисков поставщиков.