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

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

Объединить функции быстрой загрузки и восстановления.

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

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 (bootloader).
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 и выше для поддержки прошивки образов оперативной памяти от производителя.

Получает общий размер раздела и размер фрагмента. Получает данные для каждого фрагмента, затем объединяет данные в файл <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 . Возвращает ошибку, если заголовок vendor boot имеет версию 3. Если это версия 4, находит правильный фрагмент образа vendor ramdisk (если он доступен). Заменяет его заданным образом, пересчитывает размеры и смещения и прошивает новый 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 Перезагружается в режим fastboot.
reboot recovery Перезагружается в режим восстановления.
getvar Получает переменную загрузчика, необходимую для прошивки образа восстановления/загрузки (например, current-slot и max-download-size ).
oem <command> Команда определена производителем оборудования.

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

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

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

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

Fastboot OEM HAL

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

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

Для проверки загрузки пользовательского пространства в режиме fastboot запустите набор тестов поставщика (VTS) .

флеш-накопители от производителя

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

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

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

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

Изменения 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, то происходит следующее:

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

mkbootimg

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

Изменения в SELinux

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