| <html devsite> |
| <head> |
| <title>Flashing, Booting, and Updating</title> |
| <meta name="project_path" value="/_project.yaml" /> |
| <meta name="book_path" value="/_book.yaml" /> |
| </head> |
| <body> |
| <!-- |
| Copyright 2017 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <h2 id="flashing-images">Flashing images</h2> |
| <p> |
| The <code>flash</code> command should not erase the partition unless the host |
| <code>fastboot</code> tool sends an <code>erase</code> 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 |
| <code>fastboot</code> host side tool. |
| </p> |
| <p> |
| Sanity checks should be done on radio and bootloader images prior to flashing in |
| unlocked mode. For examples, compare to <code>android-info.txt</code> 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). |
| </p> |
| <p> |
| On Google-branded devices, flashing to older versions of |
| bootloaders should work properly, starting from the first commercially-shipped |
| bootloader -- ideally sooner. |
| </p> |
| <h2 id="booting-kernel-command-line">Booting: kernel command line</h2> |
| <p> |
| The kernel command line should be concatenated together from the following |
| locations: |
| </p> |
| <ul> |
| <li>bootloader command line: set of static and dynamic parameters determined by |
| the bootloader</li> |
| <li>device-tree: from the chosen/bootargs node</li> |
| <li><code>defconfig</code>: from CONFIG_CMDLINE</li> |
| <li><code>boot.img</code>: from cmdline (see |
| <a |
| href="https://android.googlesource.com/platform/system/core/+/master/mkbootimg/include/bootimg/bootimg.h" |
| class="external"><code>system/core/mkbootimg/bootimg.h</code></a> for offsets and |
| sizes)</li> |
| <li>A canonical reboot or shutdown reason compliant with the <a |
| href="/compatibility/cdd">Android Compatibility Definition Document</a> as |
| determined via PMIC (power management integrated circuit), other hardware |
| resources and reboot magic arguments (<code>LINUX_REBOOT_CMD_RESTART2</code>) |
| messaging, to land as: |
| <code>androidboot.bootreason=<reason></code></li> |
| |
| </ul> |
| <h2 id="booting-device-tree">Booting: device tree/device tree overlays</h2> |
| <p> |
| 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. |
| </p> |
| <h3 id="kaslr-seed-from-bootloader">Supporting Kernel Address Space Layout Randomization</h3> |
| <p> |
| 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. |
| </p> |
| |
| <h2 id="implementing-verified-boot">Implementing verified boot</h2> |
| <p> |
| Refer to <a |
| href="/security/verifiedboot/verified-boot.html">Verifying |
| Boot.</a> |
| </p> |
| <h2 id="supporting-updates">Supporting updates</h2> |
| <p> |
| To support the Google <a |
| href="/devices/tech/ota/">over-the-air</a> (GOTA) |
| update process a recovery RAM disk must be present. |
| </p> |
| |
| <p> |
| 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. |
| </p> |
| <p> |
| See <a |
| href="https://android.googlesource.com/platform/bootable/recovery/+/master/bootloader_message/include/bootloader_message/bootloader_message.h#64" |
| class="external"><code>bootable/recovery/bootloader_message/bootloader_message.h</code></a> |
| for details regarding the content of a block in flash that is used for recovery |
| and the bootloader to communicate. |
| </p> |
| <h3 id="a-b-updates">A/B updates</h3> |
| <p> |
| If the OEM chooses to support <a href="/devices/tech/ota/ab/">A/B |
| updates</a> for a given device, the bootloader should meet the following |
| criteria: |
| </p> |
| <ul> |
| <li>All the partitions that get updated through an OTA should be updatable |
| while the main system is booted and not through recovery. |
| <li>For A/B updates, the updater will query the <a href="/reference/hidl/android/hardware/boot/1.0/IBootControl">boot control HAL</a>, update the |
| boot slot not currently in use, change the active slot through the HAL, and |
| reboot into the updated operating system. See <a href="/devices/tech/ota/ab/ab_implement#bootcontrol" class="external">Implementing the boot control HAL</a> |
| <li>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 |
| <code>has-slot:<partition base name></code> with a value of: "yes" |
| <li>Slots are named alphabetically as a, b, c, etc. corresponding to partitions |
| with the suffix _a, _b, _c, etc. |
| <li>The bootloader should in one of these ways to inform the operating system |
| which slot was booted: <ul> |
| <li>DT property: |
| <code>/firmware/android/slot_suffix</code> |
| Or: |
| <li>Command line property: |
| <code>androidboot.slot_suffix</code> |
| </ul> |
| <li>The bootloader should support the boot_control HAL |
| (<code>hardware/libhardware/include/hardware/boot_control.h</code>). |
| <li>To boot <code>/system</code> under A/B, the bootloader should pass <code>ro |
| root=/dev/[node] rootwait skip_initramfs init=/init</code> on the kernel command |
| line. |
| Not passing skip_initramfs will boot to recovery. |
| <li><code>slot-retry-count</code> is reset to a positive value (usually "3") |
| either by the boot control HAL through the <code>setActiveBootSlot</code> |
| callback or through the <code>fastboot set_active</code> command. |
| <li>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.</li> |
| </li> |
| <li> |
| 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: |
| </li><ol> |
| <li>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. |
| <li>Is the current slot not marked as <code>slot-successful</code> AND |
| <code>slot-retry-count</code> = 0?<br/> |
| 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. |
| <li>Select appropriate boot.img and include path to correct system partition on |
| kernel command line. |
| <li>If not booting recovery, add skip_initramfs to kernel command line |
| <li>Populate DT or command line slot_suffix parameter |
| <li>Boot. If not marked "slot-successful", decrement slot-retry-count. |
| <figure id="bootloader-flow"> |
| <img src="/devices/bootloader/images/bootloader_slotting.png" |
| width="786" |
| alt="Bootloader slotting flow"> |
| <figcaption><b>Figure 1.</b> Bootloader slotting flow</figcaption> |
| </figure> |
| </li></ol> |
| <li>The fastboot utility will determine which partition to |
| flash when running any of the flashing commands: for example <code>fastboot |
| flash system system.img</code> will first query the |
| <code>current-slot</code> variable then concatenate the result to |
| system to generate the name of the partition that should be flashed (eg system_a |
| or system_b) |
| <li>When setting the current slot via fastboot <code>set_active</code> or the |
| boot control HAL's <code>setActiveBootSlot</code>, the bootloader should update |
| the current slot, clear <code>slot-unbootable</code>, clear |
| <code>slot-successful</code>, and reset the <code>retry-count</code>. These are |
| the only ways to clear <code>slot-unbootable</code>. |
| <li>It is the responsibility of the Android framework to call |
| <code>markBootSuccessful</code> from the HAL. The bootloader should |
| never mark a partition as successfully booted.</li> |
| </ul> |
| <h3 id="gota-updates-with-recovery-mode">Non-A/B updates</h3> |
| <p><a href="/devices/tech/ota/nonab/">Non-A/B updatable</a> devices should meet |
| these criteria to support updates:</p> |
| <ul> |
| <li>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. |
| <li>The bootloader should support rebooting directly into recovery mode. |
| <li>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: |
| <ul> |
| <li>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. |
| <li>The recovery image flashes the radio. This functionality may be |
| provided in the form of a binary library or utility.</li></ul> |
| </li> |
| </ol> |
| </body> |
| </html> |