The bootloader relies upon the following images.
Boot. These images contain a kernel and ramdisk image combined using an unmodified
mkbootimg(for the implementation, refer to
system/core/mkbootimg. The bootloader reads the
bootimg.hheader file generated by
mkbootimgand updates the kernel header to contain the correct location and size of the ramdisk 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.
Kernel. These images use a standard Linux format (such as
Image.gz) and can be flashed independently, combined with ramdisk images, flashed to the
bootpartition, or booted from memory. When creating kernel images, concatenated device-tree binaries are recommended (instead of 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.
Ramdisk. These images contain a root file system suitable for mounting as a
rootfs. They are combined with kernel images using
mkbootfsthen flashed into the boot partition.
File system. These images include
recoveryimages and must use Yaffs2 format or sparse image format.
File system images can be Yaffs2 format or sparse image format.
Devices using raw NAND storage must use images in Yaffs2 format generated by an
mkyaffs2image (in AOSP, refer to
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.
For details on the image format, refer to the Yaffs 2 Specification.
All Android devices should support the sparse image format.
For details, refer to
For the implementation, refer to
Devices using block-based storage should support
f2fs. To quickly
transfer and flash large, empty
ext4 file systems (such as
the image in a sparse format that contains information about which areas of the
file system can be left unwritten.
The sparse image format contains a file header, followed by a series of chunks. The file header, chunk header, and chunk data are multiples of 4 bytes, and all fields are unsigned little-endian.
The file header uses the following format:
- 32-bit magic: 0xed26ff3a
- 16-bit major version (0x1) - reject images with higher major versions
- 16-bit minor version (0x0) - allow images with higher minor versions
- 16-bit file header size in bytes (28 in v1.0)
- 16-bit chunk header size in bytes (12 in v1.0)
- 32-bit block size in bytes, must be multiple of 4
- 32-bit total blocks in output file
- 32-bit total chunks in input file
- 32-bit CRC32 checksum of original data, counting "don't care" as 0 Standard 802.3 polynomial (using a public domain table implementation).
A file chunk uses the following format:
- 16-bit chunk type:
- 0xCAC1 raw (followed by size in blocks * block size in bytes)
- 0xCAC2 fill (followed by 4 bytes of fill data)
- 0xCAC3 don't care (followed by 0 bytes)
- 16 bits reserved (write as 0, ignore on read)
- 32-bit chunk size in blocks in output image
- 32-bit total size in bytes of chunk input file including chunk header and data
Creating sparse images
You can use the
mke2fs utility to create images in sparse image format (this
is also the tool used to create the images the bootloader reads and flashes).
Implementing the writer
mke2fs utility knows what areas of the image need to be written and
encodes "don't care" chunks between them. Another tool,
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.
Implementing the reader
Readers should reject images with unknown major versions but accept images with unknown minor versions. Readers might reject images with chunk sizes they don't support. Ater the major version is validated, the reader should ignore chunks with unknown type fields, skipping over the chunk in the file using the "chunk size in file" and skipping "chunk size in blocks" blocks on the output.
A cyclic redundancy check (802.3 CRC32) should be calculated for the data that
is written to disk. Any area that isn't 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.
simg2img converts the sparse image format to a standard image,
which loses the sparse information.
flash command shouldn't erase the partition unless the host
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 demand 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 passes validation during boot (which might include
On Google-branded devices, flashing to older versions of bootloaders should work
properly, starting from the first commercially-shipped bootloader. For details
on the fastboot protocol, refer to