Moving Fastboot to User Space

Android 10 adds support for resizable partitions by relocating the fastboot implementation from bootloader to user space. 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).

Unified fastboot and recovery

Because userspace fastboot and recovery are similar, you can merge them into one partition/binary. Advantages include less space use and fewer partitions overall, as well as the ability for 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 should write boot-fastboot into the command field of the BCB message and leave 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.

New adb commands

This section describes the additional adb command necessary to integrate fastbootd. The command has differing behavior depending on whether system or recovery executes the command.

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

New fastboot commands

This section describes the additional fastboot commands necessary to integrate fastbootd, including new commands for flashing and managing logical partitions. Some commands have differing 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 is usually not).
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 wiping the partition).
resize-logical-partition <partition> <size> Resizes the logical partition to the new size without changing its contents. Fails if not enough space is 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.

fastbootd continues to support the following pre-existing fastboot commands.

Command Description
flash <partition> [ <filename> ] Writes a file to a flash partition. Device must be in unlocked state.
erase <partition> Erases a partition (not required to be secure erase). Device must be in 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, etc. and differentiated by adding the suffixes _a, _b, etc. to the partition name.

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

Modifications to the bootloader

Bootloader continues to support flashing the bootloader, radio, and boot/recovery partition, after which the device boots into fastboot (user space) and flashes all other partitions. Bootloader is expected to 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 defined by OEM.

Bootloader must not allow the flashing of dynamic partitions and must return an error that Partition should be flashed in fastbootd. For retrofitted dynamic partition devices, the fastboot tool supports a force mode to directly flash a dynamic partition while in bootloader mode. Bootloaders can support this operation. For example, if system is a dynamic partition on the retrofitted device, fastboot --force flash system allows the bootloader to flash the partition instead of fastbootd. This force mode is intended to provide flexibility in factory flashing and isn't recommended for developers.

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 not 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 oemCmdArgs 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 device.mk: PRODUCT_PACKAGES += fastbootd.

  2. Ensure 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.

Validating user space fastboot

The Vendor Test Suite (VTS) includes tests for validating user space fastboot.