1 <html devsite> 2 <head> 3 <title>A/B (Seamless) System Updates</title> 4 <meta name="project_path" value="/_project.yaml" /> 5 <meta name="book_path" value="/_book.yaml" /> 6 </head> 7 <body> 8 <!-- 9 Copyright 2017 The Android Open Source Project 10 11 Licensed under the Apache License, Version 2.0 (the "License"); 12 you may not use this file except in compliance with the License. 13 You may obtain a copy of the License at 14 15 http://www.apache.org/licenses/LICENSE-2.0 16 17 Unless required by applicable law or agreed to in writing, software 18 distributed under the License is distributed on an "AS IS" BASIS, 19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 See the License for the specific language governing permissions and 21 limitations under the License. 22 --> 23 24 25 26 <p> 27 A/B system updates, also known as seamless updates, ensure a workable booting 28 system remains on the disk during an <a href="/devices/tech/ota/index.html" 29 >over-the-air (OTA) update</a>. This reduces the likelihood of an inactive 30 device afterward, which means less device replacements and device reflashes at 31 repair/warranty centers. 32 </p> 33 34 <p> 35 Customers can continue to use their devices during an OTA. The only downtime 36 during an update is when the device reboots into the updated disk partition. If 37 the OTA fails, the device is still useable since it will boot into the pre-OTA 38 disk partition. The download of the OTA can be attempted again. A/B system 39 updates implemented through OTA are recommended for new devices only. 40 </p> 41 42 <p> 43 A/B system updates affect: 44 </p> 45 46 <ul> 47 <li>Interactions with the bootloader</li> 48 <li>Partition selection</li> 49 <li>The build process</li> 50 <li>OTA update package generation</li> 51 </ul> 52 53 <p> 54 The existing <a href="/security/verifiedboot/dm-verity.html" 55 >dm-verity</a> feature guarantees the device will boot an uncorrupted image. If 56 a device doesn't boot, because of a bad OTA or dm-verity issue, the device can 57 reboot into an old image. 58 </p> 59 60 <p> 61 The A/B system is robust because any errors (such as I/O errors) affect only 62 the <strong>unused</strong> partition set and can be retried. Such errors also 63 become less likely because the I/O load is deliberately low to avoid degrading 64 the user experience. 65 </p> 66 67 <p> 68 OTA updates can occur while the system is running, without interrupting the 69 user. This includes the app optimizations that occur after a reboot. 70 Additionally, the cache partition is no longer used to store OTA update 71 packages; there is no need for sizing the cache partition. 72 </p> 73 74 <h2 id="overview">Overview</h2> 75 76 <p> 77 A/B system updates use a background daemon called <code>update_engine</code> 78 and two sets of partitions. The two sets of partitions are referred to as 79 <em>slots</em>, normally as slot A and slot B. The system runs from one slot, 80 the <em>current</em> slot, while the partitions in the <em>unused</em> slot are 81 not accessed by the running system (for normal operation). 82 </p> 83 84 <p> 85 The goal of this feature is to make updates fault resistant by keeping the 86 unused slot as a fallback. If there is an error during an update or immediately 87 after an update, the system can rollback to the old slot and continue to have a 88 working system. To achieve this goal, none of the partitions used by the 89 <em>current</em> slot should be updated as part of the OTA update (including 90 partitions for which there is only one copy). 91 </p> 92 93 <p> 94 Each slot has a <em>bootable</em> attribute, which states whether the slot 95 contains a correct system from which the device can boot. The current slot is 96 clearly bootable when the system is running, but the other slot may have an old 97 (still correct) version of the system, a newer version, or invalid data. 98 Regardless of what the <em>current</em> slot is, there is one slot which is the 99 <em>active</em> or preferred slot. The active slot is the one the bootloader 100 will boot from on the next boot. Finally, each slot has a <em>successful</em> 101 attribute set by the user space, which is only relevant if the slot is also 102 bootable. 103 </p> 104 105 <p> 106 A successful slot should be able to boot, run, and update itself. A bootable 107 slot that was not marked as successful (after several attempts were made to 108 boot from it) should be marked as unbootable by the bootloader, including 109 changing the active slot to another bootable slot (normally to the slot running 110 right before the attempt to boot into the new, active one). The specific 111 details of the interface are defined in 112 <code><a class="external-link" target="_blank" 113 href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h" 114 >boot_control.h</a></code>. 115 </p> 116 117 <h3 id="bootloader-state-examples">Bootloader state examples</h3> 118 119 <p> 120 The <code>boot_control</code> HAL is used by <code>update_engine</code> (and 121 possibly other daemons) to instruct the bootloader what to boot from. These 122 are common example scenarios and their associated states: 123 </p> 124 125 <ul> 126 <li> 127 <strong>Normal case</strong>: The system is running from its current slot, 128 either slot A or B. No updates have been applied so far. The system's current 129 slot is bootable, successful, and the active slot. 130 </li> 131 <li> 132 <strong>Update in progress</strong>: The system is running from slot B, so 133 slot B is the bootable, successful, and active slot. Slot A was marked as 134 unbootable since the contents of slot A are being updated but not yet 135 completed. A reboot in this state should continue booting from slot B. 136 </li> 137 <li> 138 <strong>Update applied, reboot pending</strong>: The system is running from 139 slot B, slot B is bootable and successful, but slot A was marked as active 140 (and therefore is marked as bootable). Slot A is not yet marked as successful 141 and some number of attempts to boot from slot A should be made by the 142 bootloader. 143 </li> 144 <li> 145 <strong>System rebooted into new update</strong>: The system is running from 146 slot A for the first time, slot B is still bootable and successful while slot 147 A is only bootable, and still active but not successful. A user space daemon 148 should mark slot A as successful after some checks are made. 149 </li> 150 </ul> 151 152 <h3 id="update-engine-features">Update Engine features</h3> 153 154 <p> 155 The <code>update_engine</code> daemon runs in the background and prepares the 156 system to boot into a new, updated version. The <code>update_engine</code> 157 daemon is not involved in the boot process itself and is limited in what it can 158 do during an update. The <code>update_engine</code> daemon can do the 159 following: 160 </p> 161 162 <ul> 163 <li> 164 Read from the current slot A/B partitions and write any data to the unused 165 slot A/B partitions as instructed by the OTA package 166 </li> 167 <li> 168 Call the <code>boot_control</code> interface in a pre-defined workflow 169 </li> 170 <li> 171 Run a <em>post-install</em> program from the <em>new</em> partition after 172 writing all the unused slot partitions, as instructed by the OTA package 173 </li> 174 </ul> 175 176 <p> 177 The post-install step is described in detail below. Note that the 178 <code>update_engine</code> daemon is limited by the 179 <a href="/security/selinux/">SELinux</a> policies and features in the 180 <em>current</em> slot; those policies and features can't be updated until the 181 system boots into a new version. To achieve a robustness goal, the update 182 process should not: 183 </p> 184 185 <ul> 186 <li>Modify the partition table</li> 187 <li>Modify the contents of partitions in the current slot</li> 188 <li> 189 Modify the contents of non-A/B partitions that can't be wiped with a 190 factory reset 191 </li> 192 </ul> 193 194 <h2 id="life-of-an-a-b-update">Life of an A/B update</h2> 195 196 <p> 197 The update process starts when an OTA package, referred to in code as a 198 <em>payload</em>, is available for downloading. Policies in the device may 199 defer the payload download and application based on battery level, user 200 activity, whether it is connected to a charger, or other policies. But since 201 the update runs in the background, the user might not know that an update is 202 in progress and the process can be interrupted at any point due to policies or 203 unexpected reboots. 204 </p> 205 206 <p> 207 The steps in the update process after a payload is available are as follows: 208 </p> 209 210 <p> 211 <strong>Step 1:</strong> The current slot (or "source slot") is marked as 212 successful (if not already marked) with <code>markBootSuccessful()</code>. 213 </p> 214 215 <p> 216 <strong>Step 2:</strong> The unused slot (or "target slot") is marked as 217 unbootable by calling the function <code>setSlotAsUnbootable()</code>. 218 </p> 219 220 <p> 221 The current slot is always marked as successful at the beginning of the update 222 to prevent the bootloader from falling back to the unused slot, which will soon 223 have invalid data. If the system has reached the point where it can start 224 applying an update, the current slot is marked as successful even if other 225 major components are broken (such as the UI in a crash loop) since it's 226 possible to push new software to fix these major problems. 227 </p> 228 229 <p> 230 The update payload is an opaque blob with the instructions to update to the 231 new version. The update payload consists of basically two parts: the metadata 232 and the extra data associated with the instructions. The metadata is 233 relatively small and contains a list of operations to produce and verify the 234 new version on the target slot. For example, an operation could decompress a 235 certain blob and write it to certain blocks in a target partition, or read from 236 a source partition, apply a binary patch, and write to certain blocks in a 237 target partition. The extra data associated to the operations, not included in 238 the metadata, is the bulk of the update payload and would consist of the 239 compressed blob or binary patch in these examples. 240 </p> 241 242 <p> 243 <strong>Step 3:</strong> The payload metadata is downloaded. 244 </p> 245 246 <p> 247 <strong>Step 4:</strong> For each operation defined in the metadata, in order, 248 the associated data (if any) is downloaded to memory, the operation is applied, 249 and the associated memory is discarded. 250 </p> 251 252 <p> 253 These two steps take most of the update time, as they involve writing and 254 downloading large amounts of data, and are likely to be interrupted for reasons 255 of policy or reboot. 256 </p> 257 258 <p> 259 <strong>Step 5:</strong> The whole partitions are re-read and verified against 260 the expected hash. 261 </p> 262 263 <p> 264 <strong>Step 6:</strong> The post-install step (if any) is run. 265 </p> 266 267 <p> 268 In the case of an error during the execution of any step, the update fails and 269 is re-attempted with possibly a different payload. If all the steps so far have 270 succeeded, the update succeeds and the last step is executed. 271 </p> 272 273 <p> 274 <strong>Step 7:</strong> The <em>unused slot</em> is marked as active by 275 calling <code>setActiveBootSlot()</code>. 276 </p> 277 278 <p> 279 Marking the unused slot as active doesn't mean it will finish booting. The 280 bootloaderor system itselfcan switch the active slot back if it doesn't 281 read a successful state. 282 </p> 283 284 <h3 id="post-install-step">Post-install step</h3> 285 286 <p> 287 The post-install step consists of running a program from the "new update" 288 version while still running in the old version. If defined in the OTA package, 289 this step is mandatory and the program must return with exit code 290 <code>0</code>; otherwise, the update fails. 291 </p> 292 293 <p> 294 For every partition where a post-install step is defined, 295 <code>update_engine</code> mounts the new partition into a specific location 296 and executes the program specified in the OTA relative to the mounted 297 partition. For example, if the post-install program is defined as 298 <code>usr/bin/postinstall</code> in the system partition, this partition from 299 the unused slot will be mounted in a fixed location (for example, in 300 <code>/postinstall_mount</code>) and the 301 <code>/postinstall_mount/usr/bin/postinstall</code> command will be executed. 302 Note that for this step to work, the following are required: 303 </p> 304 305 <ul> 306 <li> 307 The old kernel needs to be able to mount the new filesystem format. The 308 filesystem type cannot change unless there's support for it in the old 309 kernel (which includes details such as the compression algorithm used if 310 using a compressed filesystem like SquashFS). 311 </li> 312 <li> 313 The old kernel needs to understand the new partition's post-install program 314 format. If using an ELF binary, it should be compatible with the old 315 kernel (e.g. a 64-bit new program running on an old 32-bit kernel if the 316 architecture switched from 32- to 64-bit builds). Also, the libraries 317 will be loaded from the old system image, not the new one, unless the loader 318 (<code>ld</code>) is instructed to use other paths or build a static binary. 319 </li> 320 <li> 321 The new post-install program will be limited by the SELinux policies defined 322 in the old system. 323 </li> 324 </ul> 325 326 <p> 327 An example case is to use a shell script as a post-install program (interpreted 328 by the old system's shell binary with a <code>#!</code> marker at the top) and 329 then set up library paths from the new environment for executing a more complex 330 binary post-install program. 331 </p> 332 333 <p> 334 Another example case is to run the post-install step from a dedicated smaller 335 partition, so the filesystem format in the main system partition can be updated 336 without incurring backward compatibility issues or stepping-stone updates, 337 allowing users to update straight to the latest version from a factory image. 338 </p> 339 340 <p> 341 Due to the SELinux policies, the post-install step is suitable for 342 performing tasks required by design on a given device or other best-effort 343 tasks: update the A/B-capable firmware or bootloader, prepare copies of some 344 databases for the new version, etc. This step is not suitable for one-off bug 345 fixes before reboot that require unforeseen permissions. 346 </p> 347 348 <p> 349 The selected post-install program runs in the <code>postinstall</code> SELinux 350 context. All the files in the new mounted partition will be tagged with 351 <code>postinstall_file</code>, regardless of what their attributes are after 352 rebooting into that new system. Changes to the SELinux attributes in the new 353 system won't impact the post-install step. If the post-install program needs 354 extra permissions, those must be added to the post-install context. 355 </p> 356 357 <h2 id="implementation">Implementation</h2> 358 359 <p> 360 OEMs and SoC vendors who wish to implement the feature must add the following 361 support to their bootloaders: 362 </p> 363 364 <ul> 365 <li> 366 Pass the <a href="#kernel-command-line-arguments">correct parameters</a> 367 to the kernel 368 </li> 369 <li> 370 Implement the <code>boot_control</code> HAL 371 (<a class="external-link nowrap" target="_blank" 372 href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h" 373 >https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/boot_control.h</a>) 374 </li> 375 <li>Implement the state machine as shown in Figure 1:</li> 376 </ul> 377 378 <img src="/devices/tech/ota/images/ab-updates-state-machine.png"> 379 380 <p class="img-caption"><strong>Figure 1.</strong> Bootloader state machine</p> 381 382 <p> 383 The boot control HAL can be tested using the 384 <a class="external-link" target="_blank" 385 href="https://android.googlesource.com/platform/system/extras/+/master/bootctl/" 386 ><code>bootctl</code></a> utility. 387 </p> 388 389 <p>Some tests have been implemented for Brillo:</p> 390 391 <ul> 392 <li> 393 <a class="external-link nowrap" target="_blank" 394 href="https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/" 395 >https://android.googlesource.com/platform/system/extras/+/refs/heads/master/tests/bootloader/</a> 396 </li> 397 <li> 398 <a class="external-link nowrap" target="_blank" 399 href="https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/server/site_tests/brillo_BootLoader/brillo_BootLoader.py" 400 >https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/server/site_tests/brillo_BootLoader/brillo_BootLoader.py</a> 401 </li> 402 </ul> 403 404 <h3 id="kernel-patches">Kernel patches</h3> 405 406 <ul> 407 <li> 408 <a class="external-link nowrap" target="_blank" 409 href="https://android-review.googlesource.com/#/c/158491/" 410 >https://android-review.googlesource.com/#/c/158491/</a> 411 </li> 412 <li> 413 <a class="external-link nowrap" target="_blank" 414 href="https://android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18" 415 >https://android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18</a> 416 </li> 417 </ul> 418 419 <h3 id="kernel-command-line-arguments">Kernel command line arguments</h3> 420 421 <p> 422 The kernel command line arguments <strong>must</strong> contain the following 423 extra arguments: 424 </p> 425 426 <pre class="devsite-click-to-copy"> 427 <code class="devsite-terminal">skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 \ 428 android-verity <public-key-id> <path-to-system-partition>"</code> 429 </pre> 430 431 <p> 432 The <code><public-key-id></code> value is the ID of the public key used 433 to verify the verity table signature (see 434 <a href="/security/verifiedboot/dm-verity.html">dm-verity</a>). 435 </p> 436 437 <h4> 438 To add the .X509 certificate containing the public key to the system keyring: 439 </h4> 440 441 <ol> 442 <li> 443 Copy the .X509 certificate formatted in the <code>.der</code> 444 format to the root of the <code>kernel</code> directory. Use the following 445 <code>openssl</code> command to convert from <code>.pem</code> to 446 <code>.der</code> format (if the .X509 certificate is formatted in 447 <code>.pem</code> format): 448 <pre class="devsite-terminal devsite-click-to-copy"> 449 openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate> 450 </pre> 451 </li> 452 <li> 453 Once copied to the kernel build root, build the <code>zImage</code> to 454 include the certificate as part of the system keyring. This can be verified 455 from the following <code>procfs</code> entry (requires 456 <code>KEYS_CONFIG_DEBUG_PROC_KEYS</code> to be enabled): 457 <pre class="devsite-click-to-copy"> 458 angler:/# cat /proc/keys 459 460 1c8a217e I------ 1 perm 1f010000 0 0 asymmetri 461 Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f [] 462 2d454e3e I------ 1 perm 1f030000 0 0 keyring 463 .system_keyring: 1/4 464 </pre> 465 </li> 466 </ol> 467 468 <p> 469 Successful inclusion of the .X509 certificate indicates the presence of the 470 public key in the system keyring. The highlighted portion denotes the public 471 key ID. 472 </p> 473 474 <p> 475 As the next step, replace the space with # and pass it as 476 <code><public-key-id></code> in the kernel command line. For example, in the 477 above case, the following is passed in the place of 478 <code><public-key-id></code>: 479 <code>Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f</code> 480 </p> 481 482 <h3 id="recovery">Recovery</h3> 483 484 <p> 485 The recovery RAM disk is now contained in the <code>boot.img</code> file. When 486 going into recovery, the bootloader <strong>cannot</strong> put the 487 <code>skip_initramfs</code> option on the kernel command line. 488 </p> 489 490 <h3 id="build-variables">Build variables</h3> 491 492 <h5>Must define for the A/B target:</h5> 493 494 <ul> 495 <li><code>AB_OTA_UPDATER := true</code></li> 496 <li> 497 <code>AB_OTA_PARTITIONS := \</code><br/> 498 <code> boot \</code><br/> 499 <code> system \</code><br/> 500 <code> vendor</code><br/> 501 and other partitions updated through <code>update_engine</code> (radio, 502 bootloader, etc.) 503 </li> 504 <li> 505 <code>BOARD_BUILD_SYSTEM_ROOT_IMAGE := true</code> 506 </li> 507 <li><code>TARGET_NO_RECOVERY := true</code></li> 508 <li> 509 <code>BOARD_USES_RECOVERY_AS_BOOT := true</code> 510 </li> 511 <li> 512 <code>PRODUCT_PACKAGES += \</code><br/> 513 <code> update_engine \</code><br/> 514 <code> update_verifier</code> 515 </li> 516 </ul> 517 518 <h5>Optionally define for debug builds:</h5> 519 520 <ul> 521 <li> 522 <code>PRODUCT_PACKAGES_DEBUG += update_engine_client</code> 523 </li> 524 </ul> 525 526 <h5>Cannot define for the A/B target:</h5> 527 528 <ul> 529 <li><code>BOARD_RECOVERYIMAGE_PARTITION_SIZE</code></li> 530 <li><code>BOARD_CACHEIMAGE_PARTITION_SIZE</code></li> 531 <li><code>BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE</code></li> 532 </ul> 533 534 <h3 id="partitions">Partitions</h3> 535 536 <ul> 537 <li> 538 A/B devices do not need a recovery partition or cache partition because 539 Android no longer uses these partitions. The data partition is now used for 540 the downloaded OTA package, and the recovery image code is on the boot 541 partition. 542 </li> 543 <li> 544 All partitions that are A/B-ed should be named as follows (slots are always 545 named <code>a</code>, <code>b</code>, etc.): <code>boot_a</code>, 546 <code>boot_b</code>, <code>system_a</code>, <code>system_b</code>, 547 <code>vendor_a</code>, <code>vendor_b</code>. 548 </li> 549 </ul> 550 551 <h3 id="fstab">Fstab</h3> 552 553 <p> 554 The <code>slotselect</code> argument <strong>must</strong> be on the line for 555 the A/B-ed partitions. For example: 556 </p> 557 558 <pre class="devsite-click-to-copy"> 559 <path-to-block-device>/vendor /vendor ext4 ro 560 wait,verify=<path-to-block-device>/metadata,slotselect 561 </pre> 562 563 <p> 564 Please note that there should be no partition named <code>vendor</code> but 565 instead the partition <code>vendor_a</code> or <code>vendor_b</code> will be 566 selected and mounted on the <code>/vendor</code> mount point. 567 </p> 568 569 <h3 id="kernel-slot-arguments">Kernel slot arguments</h3> 570 571 <p> 572 The current slot suffix should be passed either through a specific DT node 573 (<code>/firmware/android/slot_suffix</code>) or through the 574 <code>androidboot.slot_suffix</code> command line argument. 575 </p> 576 577 <p> 578 Optionally, if the bootloader implements fastboot, the following commands and 579 variables should be supported: 580 </p> 581 582 <h4>Commands</h4> 583 <ul> 584 <li> 585 <code>set_active <slot></code> Sets the current active slot to 586 the given slot. This must also clear the unbootable flag for that slot, and 587 reset the retry count to default values. 588 </li> 589 </ul> 590 591 <h4>Variables</h4> 592 <ul> 593 <li> 594 <code>has-slot:<partition-base-name-without-suffix></code> 595 Returns yes if the given partition supports slots, no otherwise. 596 </li> 597 <li> 598 <code>current-slot</code> Returns the slot suffix that will be booted from 599 next. 600 </li> 601 <li> 602 <code>slot-count</code> Returns an integer representing the number of 603 available slots. Currently, two slots are supported so this value is 604 <code>2</code>. 605 </li> 606 <li> 607 <code>slot-successful:<slot-suffix></code> Returns "yes" if the given 608 slot has been marked as successfully booting, "no" otherwise. 609 </li> 610 <li> 611 <code>slot-unbootable:<slot-suffix></code> Returns yes if the given 612 slot is marked as unbootable, "no" otherwise. 613 </li> 614 <li> 615 <code>slot-retry-count:<slot suffix></code> Number of retries remaining to 616 attempt to boot the given slot. 617 </li> 618 <li> 619 These variables should all appear under the following: 620 <code>fastboot getvar all</code> 621 </li> 622 </ul> 623 624 <h3 id="ota-package-generation">OTA package generation</h3> 625 626 <p> 627 The <a href="/devices/tech/ota/tools.html">OTA package tools</a> 628 follow the same commands as the commands for non-A/B devices. The 629 <code>target_files.zip</code> file must be generated by defining the build 630 variables for the A/B target. The OTA package tools automatically identify and 631 generate packages in the format for the A/B updater. 632 </p> 633 634 <p> 635 For example, use the following to generate a full OTA: 636 </p> 637 638 <pre class="devsite-terminal devsite-click-to-copy"> 639 ./build/tools/releasetools/ota_from_target_files \ 640 dist_output/tardis-target_files.zip ota_update.zip 641 </pre> 642 643 <p> 644 Or, generate an incremental OTA: 645 </p> 646 647 <pre class="devsite-terminal devsite-click-to-copy"> 648 ./build/tools/releasetools/ota_from_target_files \ 649 -i PREVIOUS-tardis-target_files.zip \ 650 dist_output/tardis-target_files.zip incremental_ota_update.zip 651 </pre> 652 653 <h2 id="configuration">Configuration</h2> 654 655 <h3 id="config-partitions">Partitions</h3> 656 657 <p> 658 The Update Engine can update any pair of A/B partitions defined in the same 659 disk. 660 </p> 661 662 <p> 663 A pair of partitions has a common prefix (such as <code>system</code> or 664 <code>boot</code>) and per-slot suffix (such as <code>_a</code>). The list of 665 partitions for which the payload generator defines an update is configured by 666 the <code>AB_OTA_PARTITIONS</code> make variable. For example, if a pair of 667 partitions <code>bootloader_a</code> and <code>booloader_b</code> are included 668 (<code>_a</code> and <code>_b</code> are the slot suffixes), these partitions 669 can be updated by specifying the following on the product or board 670 configuration: 671 </p> 672 673 <pre class="devsite-click-to-copy"> 674 AB_OTA_PARTITIONS := \ 675 boot \ 676 system \ 677 bootloader 678 </pre> 679 680 <p> 681 All the partitions updated by the Update Engine must not be modified by the 682 rest of the system. During incremental or <em>delta</em> updates, the binary 683 data from the current slot is used to generate the data in the new slot. Any 684 modification may cause the new slot data to fail verification during the 685 update process, and therefore fail the update. 686 </p> 687 688 <h3 id="post-install">Post-install</h3> 689 690 <p> 691 The post-install step can be configured differently for each updated partition 692 using a set of key-value pairs. 693 </p> 694 695 <p> 696 To run a program located at <code>/system/usr/bin/postinst</code> in a 697 new image, specify the path relative to the root of the filesystem in the 698 system partition. For example, <code>usr/bin/postinst</code> is 699 <code>system/usr/bin/postinst</code> (if not using a RAM disk). Additionally, 700 specify the filesystem type to pass to the <code>mount(2)</code> system call. 701 Add the following to the product or device <code>.mk</code> files (if 702 applicable): 703 </p> 704 705 <pre class="devsite-click-to-copy"> 706 AB_OTA_POSTINSTALL_CONFIG += \ 707 RUN_POSTINSTALL_system=true \ 708 POSTINSTALL_PATH_system=usr/bin/postinst \ 709 FILESYSTEM_TYPE_system=ext4 710 </pre> 711 712 <h3 id="compilation">App compilation in background</h3> 713 714 <p>Compiling apps in the background for A/B updates requires the following two 715 additions to the product's device configuration (in the product's device.mk):</p> 716 717 <ol> 718 <li>Include the native components in the build. This ensures the compilation 719 script and binaries are compiled and included in the system image. 720 <pre class="devsite-click-to-copy"> 721 # A/B OTA dexopt package 722 PRODUCT_PACKAGES += otapreopt_script 723 </pre> 724 </li> 725 <li>Connect the compilation script to <code>update_engine</code> such that it 726 is run as a post-install step. 727 <pre class="devsite-click-to-copy"> 728 # A/B OTA dexopt update_engine hookup 729 AB_OTA_POSTINSTALL_CONFIG += \ 730 RUN_POSTINSTALL_system=true \ 731 POSTINSTALL_PATH_system=system/bin/otapreopt_script \ 732 FILESYSTEM_TYPE_system=ext4 \ 733 POSTINSTALL_OPTIONAL_system=true 734 </pre> 735 </li> 736 </ol> 737 738 <p>See <a href="/devices/tech/dalvik/configure.html#other_odex">First 739 boot installation of DEX_PREOPT files</a> to install the preopted files in the 740 unused second system partition.</p> 741 742 </body> 743 </html> 744