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

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

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

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

Для поддержки fastbootd загрузчик должен реализовать новую команду блока управления загрузкой (BCB) boot-fastboot . Чтобы войти в режим fastbootd , загрузчик записывает boot-fastboot в командное поле сообщения BCB и оставляет поле recovery BCB неизменным (чтобы обеспечить возможность перезапуска любых прерванных задач восстановления). Поля status , stage и reserved также остаются неизменными. Загрузчик загружается и загружается в образ восстановления, увидев boot-fastboot в поле команды BCB. Затем восстановление анализирует сообщение 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 на устройстве:

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

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

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

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

Перепрошивка вендорных ramdisk

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 . Для поддержки прошивки виртуальных дисков производителя в загрузчике необходимо реализовать эти две команды.

Изменения в 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 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 внесено изменение для поддержки перепрошивки вендорных ramdisk.