Moving Fastboot to Userspace

Android 10 and higher supports resizable partitions by relocating the fastboot implementation from bootloader to userspace. This relocation enables moving the flashing code into a maintainable and testable common location with only the vendor-specific parts of fastboot implemented by a hardware abstraction layer (HAL).

Unifying fastboot and recovery

Because userspace fastboot and recovery are similar, you can merge them into one partition or binary. The advantages this provides include using less space and having fewer partitions overall, as well enabling fastboot and recovery to share their kernel and libraries.

To support fastbootd, the bootloader must implement a new boot control block (BCB) command of boot-fastboot. To enter fastbootd mode, bootloader writes boot-fastboot into the command field of the BCB message and leaves the recovery field of BCB unchanged (to enable restart of interrupted recovery tasks). The status, stage, and reserved fields remain unchanged as well. The bootloader is expected to load and boot into the recovery image upon seeing boot-fastboot in the BCB command. Recovery then parses the BCB message and switches to fastbootd mode.

ADB commands

This section describes the adb command for integrating fastbootd. The command has different behavior, depending on whether system or recovery executes it.

Command Description
reboot fastboot
  • Reboots into fastbootd (system).
  • Enters fastbootd directly without a reboot (recovery).

Fastboot commands

This section describes the fastboot commands for integrating fastbootd, including new commands for flashing and managing logical partitions. Some commands have different behavior depending on whether bootloader or fastbootd executes the command.

Command Description
reboot recovery
  • Reboots into recovery (bootloader).
  • Enters recovery directly without a reboot (fastbootd).
reboot fastboot Reboots into fastbootd.
getvar is-userspace
  • Returns yes (fastbootd).
  • Returns no (bootloader).
getvar is-logical:<partition> Returns yes if the given partition is a logical partition, no otherwise. Logical partitions support all of the commands listed below.
getvar super-partition-name Returns the name of the super partition. The name includes the current slot suffix if the super partition is an A/B partition (it usually isn't).
create-logical-partition <partition> <size> Creates a logical partition with the given name and size. The name must not already exist as a logical partition.
delete-logical-partition <partition> Deletes the given logical partition (effectively wipes the partition).
resize-logical-partition <partition> <size> Resizes the logical partition to the new size without changing its contents. Fails if there isn't enough space available to perform the resize.
update-super <partition> Merges changes to the super partition metadata. If a merge isn't possible (for example, the format on the device is an unsupported version), then this command fails. An optional wipe parameter overwrites the device's metadata, rather than performing a merge.
flash <partition> [ <filename> ] Writes a file to a flash partition. Device must be in the unlocked state.
erase <partition> Erases a partition (not required to be secure erase). Device must be in the unlocked state.
getvar <variable> | all Displays a bootloader variable, or all variables. If the variable doesn't exist, returns an error.
set_active <slot>

Sets the given A/B booting slot as active. On the next boot attempt, the system boots from the specified slot.

For A/B support, slots are duplicated sets of partitions that can be booted from independently. Slots are named a, b, and so on, and differentiated by adding the suffixes _a, _b, and so on to the partition name.

reboot Reboots device normally.
reboot-bootloader (or reboot bootloader) Reboots device into bootloader.

Fastboot and bootloader

The bootloader flashes the bootloader, radio, and boot/recovery partitions, after which the device boots into fastboot (userspace) and flashes all other partitions. The bootloader should support the following commands.

Command Description
download Downloads the image to flash.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ Flashes recovery/boot partition and bootloader.
reboot Reboots the device.
reboot fastboot Reboots to fastboot.
reboot recovery Reboots to recovery.
getvar Gets a bootloader variable that is required for flashing of recovery/boot image (for example, current-slot and max-download-size).
oem <command> Command defined by OEM.

Dynamic partitions

The bootloader must not allow the flashing or erasing of dynamic partitions and must return an error if these operations are attempted. For retrofitted dynamic partition devices, the fastboot tool (and bootloader) supports a force mode to directly flash a dynamic partition while in bootloader mode. For example, if system is a dynamic partition on the retrofitted device, using fastboot --force flash system allows the bootloader to flash the partition instead of fastbootd.

Off-mode charging

If a device supports off-mode charging or otherwise autoboots into a special mode when power is applied, the fastboot oem off-mode-charge 0 command should bypass these special modes and the device should boot as if the user had pressed the power button.

Fastboot OEM HAL

To completely replace bootloader fastboot, fastboot must handle all existing fastboot commands. Many of these commands are from OEMs and are documented but require a custom implementation. (Many commands are also OEM-specific and aren't documented). To handle such commands, the fastboot HAL specifies the required OEM commands and allows OEMs to implement their own commands.

The definition of fastboot HAL is as follows:

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);


Enabling fastbootd

To enable fastbootd on a device:

  1. Add fastbootd to PRODUCT_PACKAGES in PRODUCT_PACKAGES += fastbootd.

  2. Ensure that the fastboot HAL, boot control HAL, and health HAL are packaged as part of the recovery image.

  3. Add any device-specific SEPolicy permissions required by fastbootd. For example, fastbootd requires write access to a device-specific partition to flash that partition. In addition, fastboot HAL implementation may also require device-specific permissions.

To validate userspace fastboot, run the Vendor Test Suite (VTS).