Перенос Fastboot в пользовательское пространство

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

Объединение fastboot и recovery

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

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

Команды АБР

В этом разделе описывается команда 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> Изменяет размер логического раздела до нового размера без изменения его содержимого. Сбой, если для изменения размера недостаточно места.
update-super <partition> Объединяет изменения в метаданные суперраздела. Если слияние невозможно (например, формат на устройстве не поддерживается), эта команда завершается ошибкой. Необязательный параметр wipe перезаписывает метаданные устройства, а не выполняет слияние.
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 и выше для поддержки перепрошивки виртуальных дисков поставщиков.

Получает полный размер раздела и размер фрагмента. Получает данные для каждого фрагмента, затем объединяет данные в <out.img>

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

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

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

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

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

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

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

Для получения дополнительной информации см. fastboot flash vendor_boot: <foo> <vendor-ramdisk.img>

Фастбут и загрузчик

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

Команда Описание
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.

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

Загрузчик не должен разрешать перепрошивку или стирание динамических разделов и должен возвращать ошибку при попытке выполнения этих операций. Для модернизированных устройств с динамическими разделами средство быстрой загрузки (и загрузчик) поддерживает принудительный режим для непосредственной прошивки динамического раздела в режиме загрузчика. Например, если 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 fastboot, HAL управления загрузкой и HAL работоспособности упакованы как часть образа восстановления.

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

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

Прошивка RAM-дисков поставщиков

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

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

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

Команды 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 , он делает следующее:
      • Заменяет весь виртуальный диск поставщика заданным образом, так что указанный образ становится единственным фрагментом виртуального диска поставщика в образе vendor_boot .
      • Пересчитывает размер и смещение в таблице виртуального диска поставщика.
      • Прошивает новый образ vendor_boot .
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

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

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

      • Находит фрагмент виртуального диска поставщика с именем foo . Если не найдено или имеется несколько совпадений, возвращает ошибку.
      • Заменяет фрагмент виртуального диска поставщика на заданный образ.
      • Пересчитывает каждый размер и смещение в таблице виртуального диска поставщика.
      • Прошивает новый образ vendor_boot .

mkbootimg

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

Изменения SELinux

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