| <html devsite> |
| <head> |
| <title>Partitions and Images</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="partitions">Partitions</h2> |
| <p> |
| Android devices include several partitions that serve different functions in the |
| boot process. To support <a href="/devices/tech/ota/ab/">A/B |
| updates</a>, the device will need one slot per partition for |
| <code>boot</code>, <code>system</code>, <code>vendor</code>, and |
| <code>radio</code>. |
| </p> |
| <ul> |
| <li><strong>boot</strong>: The <code>boot</code> partition contains a kernel |
| image and a RAM disk combined via <code>mkbootimg</code>. In order to flash the |
| kernel directly without flashing a new boot partition, a virtual partition can |
| be used: <ul> |
| <li><strong>kernel</strong>: The virtual <code>kernel</code> partition |
| overwrites only the kernel (zImage, zImage-dtb, Image.gz-dtb) by writing the new |
| image over the old one. To do this, it determines the start location of the |
| existing kernel image in eMMC and copies to that location, keeping in mind that |
| the new kernel image may be larger than the existing one. The bootloader can |
| either make space by moving any data following it or abandoning the operation |
| with an error. If the development kernel supplied is incompatible, you may need |
| to update the dtb partition if present, or vendor or system partition with |
| associated kernel modules. |
| <li><strong>ramdisk</strong>: The virtual <code>ramdisk</code> partition |
| overwrites only the RAM disk by writing the new image over the old one. To do |
| this, it determines the start location of the existing <code>ramdisk.img</code> |
| in eMMC and copies to that location, keeping in mind that the new RAM disk maybe |
| be larger than the existing one. The bootloader can either make space by moving |
| any data following it or abandon the operation with an error.</ul> |
| <li><strong>system</strong>: The <code>system</code> partition mainly contains |
| the Android framework. |
| <li><strong>recovery</strong>: The <code>recovery</code> partition stores the |
| recovery image, booted during the OTA process. If the device supports <a |
| href="/devices/tech/ota/ab/">A/B updates</a>, |
| recovery can be a RAM disk contained in the boot image rather than a separate |
| image. |
| <li><strong>cache</strong>: The <code>cache</code> partition stores temporary |
| data and is optional if a device uses A/B updates. The cache partition doesn't |
| need to be writable from the bootloader, only erasable. The size depends on the |
| device type and the availability of space on userdata. Currently 50MB-100MB |
| should be ok. |
| <li><strong>misc</strong>: The <code>misc</code> partition is used by recovery |
| and is 4KB or larger. |
| <li><strong>userdata</strong>: The <code>userdata</code> partition contains |
| user-installed applications and data, including customization data. |
| <li><strong>metadata</strong>: The <code>metadata</code> partition is used when |
| device is encrypted and is 16MB or larger. |
| <li><strong>vendor</strong>: The <code>vendor</code> partition contains any |
| binary that is not distributable to the Android Open Source Project (AOSP). If |
| there is no proprietary information, this partition may be omitted. |
| <li><strong>radio</strong>: The <code>radio</code> partition contains the radio |
| image. This partition is only necessary for devices that include a radio that |
| have radio-specific software in a dedicated partition. |
| <li><strong>tos</strong>: The <code>tos</code> partition stores the binary image |
| of the Trusty OS and is only used if the device includes Trusty.</li> |
| </li></ul> |
| <h2 id="flow">Flow</h2> |
| <p> |
| Here is how the bootloader operates: |
| </p><ol> |
| <li>The bootloader gets loaded first. |
| <li>The bootloader initializes memory. |
| <li>If <a href="/devices/bootloader/flashing-updating#a-b-updates">A/B |
| updates</a> are used, determine the current slot to boot. |
| <li>Determine whether recovery mode should be booted instead as described in <a |
| href="/devices/bootloader/flashing-updating#supporting-updates">Supporting |
| updates</a>. |
| <li>The bootloader loads the image, which contains the kernel and RAM disk (and |
| in <a href="/devices/architecture/treble">Treble</a> even more). |
| <li>The bootloader starts loading the kernel into memory as a self-executable |
| compressed binary. |
| <li>The kernel decompresses itself and starts executing into memory. |
| <li>From there on, older devices load <code>init</code> from the RAM disk and |
| newer devices load it from the <code>/system</code> partition. |
| <li>From <code>/system</code>, <code>init</code> launches and starts mounting |
| all the other partitions, such as <code>/vendor</code>, <code>/oem</code>, and |
| <code>/odm</code>, and then starts executing code to start the device</li> |
| </ol> |
| <h2 id="images">Images</h2> |
| <p> |
| The bootloader relies upon these images. |
| </p> |
| <h3 id="kernel-images">Kernel images</h3> |
| <p> |
| Kernel images are created in a standard Linux format, such as zImage, Image, or |
| Image.gz. Kernel images can be flashed independently, combined with RAM disk |
| images, and flashed to the boot partition or booted from memory. When creating |
| kernel images, concatenated device-tree binaries are recommended over using a |
| separate partition for the device tree. When using multiple Device Tree Blobs |
| (DTBs) for different board revisions, concatenate multiple DTBs in descending |
| order of board revision. |
| </p> |
| <h3 id="ram-disk-images">RAM disk images</h3> |
| <p> |
| RAM disks should contain a root file system suitable for mounting as a rootfs. |
| RAM disk images are combined with kernel images using mkbootfs and then flashed |
| into the boot partition. |
| </p> |
| <h3 id="boot-images">Boot images</h3> |
| <p> |
| Boot images should contain a kernel and RAM disk combined using an unmodified |
| <code>mkbootimg</code>. |
| </p> |
| <p> |
| The <code>mkbootimg</code> implementation can be found at: <code><a |
| href="https://android.googlesource.com/platform/system/core/+/master/mkbootimg">system/core/mkbootimg</a></code> |
| </p> |
| <p> |
| The bootloader reads the <code><a |
| href="https://android.googlesource.com/platform/system/core/+/master/mkbootimg/bootimg.h">bootimg.h</a></code> |
| header file generated by mkbootimg and updates the kernel header to contain the |
| correct location and size of the RAM disk in flash, base address of the kernel, |
| command line parameters, and more. The bootloader then appends the command line |
| specified in the boot image to the end of the bootloader-generated command |
| line. |
| |
| <h3 id="file-system-images-system-userdata-recovery">File system images (system, |
| userdata, recovery)</h3> |
| <h4 id="sparse-image-format">YAFFS2 image format</h4> |
| <p> |
| If using raw NAND storage, these images must be YAFFS2, generated by an unmodified mkyaffs2image, as found in the Android Open Source Project (AOSP) at <a href="https://android.googlesource.com/platform/external/yaffs2/+/master/yaffs2/utils/" class="external"><code>external/yaffs2/yaffs2/utils</code></a>. They have the format: |
| <pre> |
| <code> |
| | 2k bytes of data| yaffs extra data | padding | | 0 2048 | 0 64 | variable| |
| </code> |
| </pre> |
| <p> |
| The bootloader is responsible for consuming these images and relocating the |
| yaffs extra data into the appropriate location in the out-of-band area for the |
| given nand hardware. If software ECC is required, the bootloader should also |
| do that computation at this time. |
| </p> |
| <h4 id="sparse-image-format">Sparse image format</h4> |
| <p> |
| The sparse image format should be supported. It is described in the document |
| "ext4 compressed images" and in <code><a |
| href="https://android.googlesource.com/platform/system/core/+/master/libsparse/sparse_format.h">system/core/libsparse/sparse_format.h</a></code>; |
| it is implemented in: <code><a |
| href="https://android.googlesource.com/platform/system/core/+/master/libsparse/sparse_read.cpp">system/core/libsparse/sparse_read.cpp</a></code> |
| </p> |
| <p> |
| If using a block-based storage device, ext4 or f2fs should be supported. To |
| quickly transfer and flash large, empty ext4 file systems (userdata), store the |
| image in a sparse format that contains information about which areas of the file |
| system can be left unwritten. The file format is written by the |
| <code>mke2fs</code> utility that is also used to create the images the file |
| format is read and flashed by the bootloader. See the sections below for |
| attributes: |
| </p> |
| <p> |
| |
| <h5 id="file-format">File format</h5> |
| <ul> |
| <li>All fields are unsigned little-endian |
| <li>The file contains a file header, followed by a series of chunks |
| <li>The file header, chunk header, and chunk data are all multiples of 4 bytes |
| long</li></ul> |
| <h5 id="header">Header</h5> |
| <ul> |
| <li>32-bit magic: 0xed26ff3a |
| <li>16-bit major version (0x1) - reject images with higher major versions |
| <li>16-bit minor version (0x0) - allow images with higher minor versions |
| <li>16-bit file header size in bytes (28 in v1.0) |
| <li>16-bit chunk header size in bytes (12 in v1.0) |
| <li>32-bit block size in bytes, must be multiple of 4 |
| <li>32-bit total blocks in output file |
| <li>32-bit total chunks in input file</li></ul> |
| <p> |
| 32-bit CRC32 checksum of original data, counting "don't care" as 0 Standard |
| 802.3 polynomial, use a public domain table implementation |
| </p> |
| <h5 id="chunk">Chunk</h5> |
| <ul> |
| <li>16-bit chunk type: |
| <ul> |
| <li>0xCAC1 raw |
| <li>0xCAC2 fill |
| <li>0xCAC3 don't care |
| </ul> |
| <li>16 bits reserved (write as 0, ignore on read) |
| <li>32-bit chunk size in blocks in output image |
| <li>32-bit total size in bytes of chunk input file including chunk header and |
| data</li></ul> |
| <h5 id="data">Data</h5> |
| <ul> |
| <li> for raw, raw data, size in blocks * block size in bytes |
| <li> for fill, 4 bytes of fill data</li></ul> |
| <h5 id="implementing-the-writer">Implementing the writer</h5> |
| <p> |
| The <code>mke2fs</code> utility already knows what areas of the image need |
| to be written, and will encode "don't care" chunks between them. Another tool, |
| <code>img2simg</code>, will convert regular (non-sparse) images to sparse |
| images. Regular images have no information about "don't care" areas; the best a |
| conversion can do is look for blocks of repeated data to reduce the resulting |
| image size. |
| </p> |
| <h5 id="implementing-the-reader">Implementing the reader</h5> |
| <p> |
| Readers should reject images with unknown major versions and should accept images |
| with unknown minor versions. Readers may reject images with chunk sizes they do |
| not support. |
| </p> |
| <p> |
| Once the major version is validated, the reader should ignore chunks with unknown |
| type fields. It should skip over the chunk in the file using the "chunk size in |
| file" and skip "chunk size in blocks" blocks on the output. |
| </p> |
| <p> |
| A Cyclic Redundancy Check - 802.3 CRC32 - should be calculated for the data that |
| will be written to disk. Any area that is not written (don't care, or a skipped |
| chunk), should be counted as 0s in the CRC. The total number of blocks written |
| or skipped should be compared against the "total blocks" field in the header. |
| The tool <code>simg2img</code> will convert the sparse image format to a |
| standard image, which will lose the sparse information. |
| </p> |
| </body> |
| </html> |