Fastboot is the name of a bootloader module and mode. 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). In addition, Android 12 and higher supports flashing ramdisks through an added fastboot command.
Unify fastboot and recovery
Because userspace fastboot and recovery are similar, you can merge them into one partition or binary. This provides advantages such as using less space, having fewer partitions overall, and having fastboot and recovery share their kernel and libraries.
Fastbootd is the name of a userspace daemon and mode. 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 restarting any interrupted recovery tasks). The status
, stage
, and reserved
fields remain unchanged as well. The bootloader loads and boots into the recovery image upon seeing boot-fastboot
in the BCB command field. 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 results, depending on whether it's executed by system or by recovery.
Command | Description |
---|---|
reboot fastboot |
|
Fastboot commands
This section describes the fastboot commands for integrating fastbootd
, including new commands for flashing and managing logical partitions. Some commands have different results, depending on whether they've been executed by bootloader or by fastbootd
.
Command | Description |
---|---|
reboot recovery |
|
reboot fastboot | Reboots into fastbootd . |
getvar is-userspace |
|
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. |
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 For A/B support, slots are duplicated sets of partitions that can be booted from independently. Slots are named |
reboot | Reboots device normally. |
reboot-bootloader (or reboot bootloader ) | Reboots device into bootloader. |
fastboot fetch vendor_boot <out.img> | Use in Android 12 and higher to support flashing vendor ramdisks. Gets the entire partition size and the chunk size. Gets data for each chunk, then stitches the data together to For details, see |
fastboot flash vendor_boot:default <vendor-ramdisk.img> | Use in Android 12 and higher to support flashing vendor ramdisks. This is a special variant of the flash command. It performs a For details, see |
fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> | Use in Android 12 and higher to support flashing vendor ramdisks. Fetches the For details, see |
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 the fastboot --force flash system
command enables the bootloader (instead of fastbootd
) to flash the partition.
Off-mode charging
If a device supports off-mode charging or otherwise autoboots into a special mode when power is applied, an implementation of the fastboot oem off-mode-charge 0
command must bypass these special modes, so that the device boots 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 OEM-specific commands aren't documented. To handle such commands, the fastboot HAL specifies the required OEM commands. OEMs can also 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);
};
Enable fastbootd
To enable fastbootd
on a device:
Add
fastbootd
toPRODUCT_PACKAGES
indevice.mk
:PRODUCT_PACKAGES += fastbootd
.Ensure that the fastboot HAL, boot control HAL, and health HAL are packaged as part of the recovery image.
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).
Flash vendor ramdisks
Android 12 and higher provides support for flashing ramdisks with an added fastboot command that pulls the full vendor_boot
image from a device. The command prompts the host-side fastboot tool to read the vendor boot header, reimage, and flash the new image.
To pull the full vendor_boot
image, the command fetch:vendor_boot
was added to both the fastboot protocol, and the fastbootd implementation of the protocol in Android 12. Note that fastbootd does implement this, but the bootloader itself might not. OEMs can add the fetch:vendor_boot
command to their bootloader implementation of the protocol. However, if the command isn't recognized in bootloader mode, then flashing individual vendor ramdisks in bootloader mode isn't a vendor-supported option.
Bootloader changes
The commands getvar:max-fetch-size
and fetch:name
are implemented in fastbootd
. To support flashing vendor ramdisks in bootloader, you must implement these two commands.
Fastbootd changes
getvar:max-fetch-size
is similar to max-download-size
. It specifies the maximum size that the device can send in one DATA response. The driver must not fetch a size larger than this value.
fetch:name[:offset[:size]]
performs a series of checks on the device. If all of the following are true, the fetch:name[:offset[:size]]
command returns data:
- The device is running a debuggable build.
- The device is unlocked (boot state orange).
- The fetched partition name is
vendor_boot
. - The
size
value falls within 0 <size
<=max-fetch-size
.
When these are verified, fetch:name[:offset[:size]]
returns the partition size and offset. Note the following:
fetch:name
is equivalent tofetch:name:0
, which is equivalent tofetch:name:0:partition_size
.fetch:name:offset
is equivalent tofetch:name:offset:(partition_size - offset)
Therefore fetch:name[:offset[:size]]
= fetch:name:offset:(partition_size - offset)
.
When offset
or partition_size
(or both) are unspecified, the default values are used, which for offset
is 0, and for size
is the calculated value of partition_size - offset
.
- Offset specified, size unspecified:
size = partition_size - offset
- Neither specified: default values used for both,
size = partition_size
- 0.
For example, fetch:foo
fetches the entire foo
partition at offset 0.
Driver changes
Commands were added to the fastboot tool to implement driver changes. Each is linked to its full definition in the table of Fastboot commands.
fastboot fetch vendor_boot out.img
- Calls
getvar max-fetch-size
to determine the chunk size. - Calls
getvar partition-size:vendor_boot[_a]
to determine the size of the entire partition. - Calls
fastboot fetch vendor_boot[_a]:offset:size
for each chunk. (The chunk size is greater than thevendor_boot
size, so there's normally only one chunk.) - Stitches the data together, to
out.img
.
- Calls
fastboot flash vendor_boot:default vendor-ramdisk.img
This is a special variant of the flash command. It fetches the
vendor_boot
image, as iffastboot fetch
was called.- If the vendor boot is header version 3, it does the following:
- Replaces the vendor ramdisk with the given image.
- Flashes the new
vendor_boot
image.
- If the vendor boot header is version 4, it does the following:
- Replaces the whole vendor ramdisk with the given image so that the given image becomes the only vendor ramdisk fragment in the
vendor_boot
image. - Recalculates the size and offset in the vendor ramdisk table.
- Flashes the new
vendor_boot
image.
- Replaces the whole vendor ramdisk with the given image so that the given image becomes the only vendor ramdisk fragment in the
- If the vendor boot is header version 3, it does the following:
fastboot flash vendor_boot:foo vendor-ramdisk.img
Fetches
vendor_boot image
, as iffastboot fetch
was called.- If the vendor boot header is version 3, it returns an error.
If the vendor boot header is version 4, it does the following:
- Finds the vendor ramdisk fragment with name
ramdisk_<var><foo></var>
. If not found, or if there are multiple matches, returns an error. - Replaces the vendor ramdisk fragment with the given image.
- Recalculates each size and offset in the vendor ramdisk table.
- Flashes the new
vendor_boot
image.
- Finds the vendor ramdisk fragment with name
If <foo> isn't specified, it tries to find
ramdisk_
.
mkbootimg
The name default
is reserved for naming vendor ramdisk fragments in Android 12 and higher. While the fastboot flash vendor_boot:default
semantics remain the same, you must not name your ramdisk fragments as default
.
SELinux changes
A change was made in fastbootd.te
to support flashing vendor ramdisks.