Flashing, Booting, and Updating

Flashing images

The flash command should not erase the partition unless the host fastboot tool sends an erase command first. This allows flashing a very large partition in multiple smaller chunks using multiple sparse images that start with a "skip" block to seek over the already-written area. Creating these images on the fly is already handled by the fastboot host side tool.

Sanity checks should be done on radio and bootloader images prior to flashing in unlocked mode. For examples, compare to android-info.txt created from the build and confirm the version matches. Also check bootloader image signature at flash time to make sure it will pass validation during boot (which may include anti-rollback features).

On Google-branded devices, flashing to older versions of bootloaders should work properly, starting from the first commercially-shipped bootloader -- ideally sooner.

Booting: kernel command line

The kernel command line should be concatenated together from the following locations:

  • bootloader command line: set of static and dynamic parameters determined by the bootloader
  • device-tree: from the chosen/bootargs node
  • defconfig: from CONFIG_CMDLINE
  • boot.img: from cmdline (see system/core/mkbootimg/bootimg.h for offsets and sizes)
  • A canonical reboot or shutdown reason compliant with the Android Compatibility Definition Document as determined via PMIC (power management integrated circuit), other hardware resources and reboot magic arguments (LINUX_REBOOT_CMD_RESTART2) messaging, to land as: androidboot.bootreason=<reason>

Booting: device tree/device tree overlays

To support various configurations, the bootloader can identify the hardware/product revision it is running on and load the correct set of device tree overlays.

Supporting Kernel Address Space Layout Randomization

In order to support randomizing the virtual address at which the kernel image is loaded (enabled by kernel config RANDOMIZE_BASE), the bootloader needs to provide entropy by passing a random u64 value in the DT node /chosen/kaslr-seed.

Implementing verified boot

Refer to Verifying Boot.

Supporting updates

To support the Google over-the-air (GOTA) update process a recovery RAM disk must be present.

If the standard AOSP recovery image is being used, during boot the bootloader should read the first 32 bytes on the misc partition and boot into the recovery image if the data there matches: "boot-recovery" This allows any pending recovery work (e.g. applying an OTA, performing data removal, etc.) to resume until being finished successfully.

See bootable/recovery/bootloader_message/bootloader_message.h for details regarding the content of a block in flash that is used for recovery and the bootloader to communicate.

A/B updates

If the OEM chooses to support A/B updates for a given device, the bootloader should meet the following criteria:

  • All the partitions that get updated through an OTA should be updatable while the main system is booted and not through recovery.
  • For A/B updates, the updater will query the boot control HAL, update the boot slot not currently in use, change the active slot through the HAL, and reboot into the updated operating system. See Implementing the boot control HAL
  • All partitions that support A/B will have a suffix appended to their name. This differentiates the partitions belonging to a particular slot in the bootloader. For each such partition, there is a corresponding variable has-slot: with a value of: "yes"
  • Slots are named alphabetically as a, b, c, etc. corresponding to partitions with the suffix _a, _b, _c, etc.
  • The bootloader should in one of these ways to inform the operating system which slot was booted:
    • DT property: /firmware/android/slot_suffix Or:
    • Command line property: androidboot.slot_suffix
  • The bootloader should support the boot_control HAL (hardware/libhardware/include/hardware/boot_control.h).
  • To boot /system under A/B, the bootloader should pass ro root=/dev/[node] rootwait skip_initramfs init=/init on the kernel command line. Not passing skip_initramfs will boot to recovery.
  • slot-retry-count is reset to a positive value (usually "3") either by the boot control HAL through the setActiveBootSlot callback or through the fastboot set_active command.
  • When modifying a partition that is part of a slot, the bootloader shall clear "successfully booted" and reset the retry_count for the slot in question.
  • The bootloader should also determine which slot to load. See the diagram within this section for a depiction of the decision flow; the general steps are:
    1. Determine which slot to attempt. Do not attempt to load a slot marked "slot-unbootable". This slot should be consistent with the values returned by fastboot, and will be referred to as the current slot from now on.
    2. Is the current slot not marked as slot-successful AND slot-retry-count = 0?
      Mark the current slot as "slot-unbootable", and select a different slot that is not marked "unbootable" and is marked as "slot-successful". This slot is now the selected slot. If no current slot is available, boot to recovery or display a meaningful error message to the user.
    3. Select appropriate boot.img and include path to correct system partition on kernel command line.
    4. If not booting recovery, add skip_initramfs to kernel command line
    5. Populate DT or command line slot_suffix parameter
    6. Boot. If not marked "slot-successful", decrement slot-retry-count.
      Bootloader slotting flow
      Figure 1. Bootloader slotting flow
  • The fastboot utility will determine which partition to flash when running any of the flashing commands: for example fastboot flash system system.img will first query the current-slot variable then concatenate the result to system to generate the name of the partition that should be flashed (eg system_a or system_b)
  • When setting the current slot via fastboot set_active or the boot control HAL's setActiveBootSlot, the bootloader should update the current slot, clear slot-unbootable, clear slot-successful, and reset the retry-count. These are the only ways to clear slot-unbootable.
  • It is the responsibility of the Android framework to call markBootSuccessful from the HAL. The bootloader should never mark a partition as successfully booted.

Non-A/B updates

Non-A/B updatable devices should meet these criteria to support updates:

  • The recovery partition should contain an image that is capable of reading a system image from some supported partition (cache, userdata) and writing it to the system partition.
  • The bootloader should support rebooting directly into recovery mode.
  • If radio image updates are supported, the recovery partition should also be able to flash the radio. This can be accomplished in one of two ways:
    • The bootloader flashes the radio. In this case, it should be possible to reboot from the recovery partition back into the bootloader to complete the update.
    • The recovery image flashes the radio. This functionality may be provided in the form of a binary library or utility.