blob: 9c05593c5aa2ac0b69edfa11e2d430f8ca54c9dd [file] [log] [blame]
<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=&lt;reason&gt;</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>