Dynamic partitioning is implemented using the dm-linear device-mapper
module in the Linux kernel. The
super partition contains
metadata listing the names and block ranges of each dynamic partition
super. During first-stage
metadata is parsed and validated, and virtual block devices are created to
represent each dynamic partition.
When applying an OTA, dynamic partitions are automatically created, resized, or deleted as needed. For A/B devices, there are two copies of the metadata, and changes are applied only to the copy representing the target slot.
Because dynamic partitions are implemented in userspace, partitions needed
by the bootloader can't be made dynamic. For example,
vbmeta are read by the bootloader, and
so must remain as physical partitions.
Each dynamic partition can belong to an update group. These
groups limit the maximum space that partitions in that group can consume.
vendor can belong to a
group that restricts the total size of
Implementing dynamic partitions on new devices
This section details how to implement dynamic partitions on new devices launching with Android 10 and higher. To update existing devices, see Upgrading Android devices.
For devices launching with Android 10, create
a partition called
partition handles A/B slots internally, so A/B devices don't need
All read-only AOSP partitions that aren't used by the bootloader must
be dynamic and must be removed from the GUID Partition Table (GPT).
Vendor-specific partitions don't have to be dynamic and may be placed
in the GPT.
To estimate the size of
super, add the sizes of the
partitions being deleted from the GPT. For A/B devices, this
should include the size of both slots. Figure 1 shows
an example partition table before and after converting to dynamic
The supported dynamic partitions are:
- System Ext
For devices launching with Android 10, the
kernel command line option
must be empty so that the command sysprop
ro.boot.super_partition is empty.
The device-mapper module may operate less efficiently if the
super partition is not properly aligned. The
super partition MUST be aligned to the minimum I/O
request size as determined by the block layer. By default, the
build system (via
lpmake, which generates the
super partition image), assumes that a 1 MiB alignment
is sufficient for every dynamic partition. However, vendors should
ensure that the
super partition is properly aligned.
You can determine the minimum request size of a block device by
sysfs. For example:
# ls -l /dev/block/by-name/super lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17 # cat /sys/block/sda/queue/minimum_io_size 786432
You can verify the
super partition's alignment in a
# cat /sys/block/sda/sda17/alignment_offset
The alignment offset MUST be 0.
Device configuration changes
To enable dynamic partitioning, add the following flag in
PRODUCT_USE_DYNAMIC_PARTITIONS := true
Board configuration changes
You're required to set the size of the
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
On A/B devices, the build system throws an error if the total size
of dynamic partition images is more than half of the
You can configure the list of dynamic partitions as follows. For
devices using update groups, list the groups in the
BOARD_SUPER_PARTITION_GROUPS variable. Each group name
then has a
For A/B devices, the maximum size of a group should cover only one
slot, as the group names are slot-suffixed internally.
Here's an example device that places all partitions into a group
BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944 BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product
Here's an example device that places system and product services into
BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar BOARD_GROUP_FOO_SIZE := 4831838208 BOARD_GROUP_FOO_PARTITION_LIST := system product_services BOARD_GROUP_BAR_SIZE := 1610612736 BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
For A/B launch devices, the sum of maximum sizes of all groups must
BOARD_SUPER_PARTITION_SIZE/ 2 - overhead
For non-A/B devices and retrofit A/B devices, the sum of maximum
sizes of all groups must be:
- At build time, the sum of the sizes of the images of each partition in an update group must not exceed the maximum size of the group.
- Overhead is required in the computation to account for metadata, alignments, and so on. A reasonable overhead is 4 MiB, but you can pick a larger overhead as needed by the device.
Sizing dynamic partitions
Before dynamic partitions, partition sizes were over-allocated to ensure that they had enough room for future updates. The actual size was taken as is and most read-only partitions had some amount of free space in their file system. In dynamic partitions, that free space is unusable and could be used to grow partitions during an OTA. It's critical to ensure that partitions aren't wasting space and are allocated to a minimum possible size.
For read-only ext4 images, the build system automatically allocates the minimum size if no hardcoded partition size is specified. The build system fits the image so that the file system has as little unused space as possible. This ensures that the device doesn't waste space that can be used for OTAs.
Additionally, ext4 images can be further compressed by enabling block- level deduplication. To enable this, use the following configuration:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
If automatic allocation of a partition minimum size is undesirable,
there are two ways to control the partition size. You can specify a
minimum amount of free space with
or you can specify
BOARD_partitionIMAGE_PARTITION_SIZE to force
dynamic partitions to a specific size. Neither of these is
recommended unless necessary.
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
This forces the file system in
product.img to have
50 MiB of unused space.
Devices launching with Android 10 must not use system-as-root.
Devices with dynamic partitions (whether it launches with or retrofits
dynamic partitions) must not use system-as-root. The Linux kernel can't
super partition and so can't mount
system is now mounted by
init, which resides in the ramdisk.
Android 10, the
BOARD_BUILD_SYSTEM_ROOT_IMAGE flag is only used to
differentiate whether the system is mounted by the kernel or by the
init in ramdisk.
causes a build error when
PRODUCT_USES_DYNAMIC_PARTITIONS is also
BOARD_USES_RECOVERY_AS_BOOT is set to true, the
recovery image is built as boot.img, containing the recovery's
ramdisk. Previously, bootloader used the
command line parameter to decide which mode to boot into. For Android
10 devices, the bootloader MUST NOT pass
skip_initramfs to the kernel command-line. Instead, bootloader
androidboot.force_normal_boot=1 to skip recovery
and boot normal Android.
AVB configuration changes
When using Android Verified Boot 2.0, if the device isn't using chained partition descriptors, then no change is necessary. If using chained partitions, however, and one of the verified partitions is dynamic, then changes are necessary.
Here's an example configuration for a device that chains
vbmeta for the
BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1 BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1
With this configuration, the bootloader expects to find a vbmeta
footer at the end of the
vendor partitions. Because these partitions are no longer
visible to the bootloader (they reside in
changes are needed.
vbmeta_vendorpartitions to the device's partition table. For A/B devices, add
vbmeta_vendor_b. If adding one or more of these partitions, they should be the same size as the
Rename the configuration flags by adding
VBMETA_and specify which partitions the chaining extends to:
BOARD_AVB_VBMETA_SYSTEM := system BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1 BOARD_AVB_VBMETA_VENDOR := vendor BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1
A device may be using one, both, or none of these partitions. Changes are need only when chaining to a logical partition.
AVB bootloader changes
If the bootloader has embedded libavb, include the following patches:
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: Only query partition GUIDs when the cmdline needs them."
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "Allow system partition to be absent"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "Fix AvbSlotVerifyData->cmdline might be NULL"
If using chained partitions, include an additional patch:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Support vbmeta blobs in beginning of partition."
Kernel command line changes
A new parameter,
androidboot.boot_devices, must be added
to the kernel command line. This is used by
/dev/block/by-name symlinks. It should be the
device path component to the underlying by-name symlink created by
ueventd, that is,
For example, if the super partition by-name symlink is
you can add the command line parameter in the BoardConfig.mk file as
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
The device tree and device tree overlays must not contain fstab entries. Use an fstab file that will be part of the ramdisk.
Changes must be made to the fstab file for logical partitions:
The fs_mgr flags field must include the
logicalflag and the
first_stage_mountflag, introduced in Android 10, which indicates that a partition is to be mounted in the first stage.
A partition may specify
avb=vbmeta partition nameas an
fs_mgrflag and then the specified
vbmetapartition is initialized by first stage
initbefore attempting to mount any devices.
devfield must be the partition name.
The following fstab entries set system, vendor, and product as logical partitions following the above rules.
#<dev> <mnt_point> <type> <mnt_flags options> <fs_mgr_flags> system /system ext4 ro,barrier=1 wait,slotselect,avb=vbmeta,logical,first_stage_mount vendor /vendor ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount product /product ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount
Copy the fstab file into the first stage ramdisk.
The super partition block device must be marked with the label
super_block_device. For example, if the super partition by-name symlink is
add the following line to
The bootloader (or any non-userspace flashing tool) doesn't understand dynamic partitions, so it can't flash them. To address this, devices must use a user-space implementation of the fastboot protocol, called fastbootd.
For more information on how to implement fastbootd, see Moving Fastboot to User Space.
For developers using eng or userdebug builds,
is extremely useful for fast iteration. Dynamic partitions pose a
adb remount because there is no longer free
space within each file system. To address this, devices can enable
overlayfs. As long as there is free space within the super partition,
adb remount automatically creates a temporary dynamic
partition and uses overlayfs for writes. The temporary partition is
scratch, so don't use this name for other
For more information on how to enable overlayfs, see the overlayfs README in AOSP.
Upgrading Android devices
If you upgrade a device to Android 10, and want to include dynamic partitions support in the OTA, you don't need to change the built-in partition table. Some extra configuration is required.
Device configuration changes
To retrofit dynamic partitioning, add the following flags in
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
Board configuration changes
You're required to set the following board variables:
BOARD_SUPER_PARTITION_BLOCK_DEVICESto the list of block devices used to store extents of dynamic partitions. This is the list of names of existing physical partitions on the device.
BOARD_SUPER_PARTITION_partition_DEVICE_SIZEto the sizes of each block device in
BOARD_SUPER_PARTITION_BLOCK_DEVICES, respectively. This is the list of sizes of existing physical partitions on the device. This is usually
BOARD_partitionIMAGE_PARTITION_SIZEin existing board configurations.
- Unset existing
BOARD_partitionIMAGE_PARTITION_SIZEfor all partitions in
BOARD_SUPER_PARTITION_SIZEto the sum of
BOARD_SUPER_PARTITION_METADATA_DEVICEto the block device where dynamic partition metadata is stored. It must be one of
BOARD_SUPER_PARTITION_BLOCK_DEVICES. Usually, this is set to
BOARD_group_PARTITION_LIST, respectively. See Board configuration changes on new devices for details.
For example, if the device already has system and vendor partitions, and you want to convert them to dynamic partitions and add a new product partition during the update, set this board configuration:
BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor BOARD_SUPER_PARTITION_METADATA_DEVICE := system # Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE. BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes> # Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes> # This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE BOARD_SUPER_PARTITION_SIZE := <size-in-bytes> # Configuration for dynamic partitions. For example: BOARD_SUPER_PARTITION_GROUPS := group_foo BOARD_GROUP_FOO_SIZE := <size-in-bytes> BOARD_GROUP_FOO_PARTITION_LIST := system vendor product
The super partition block devices must be marked with the attribute
super_block_device_type. For example, if the device already has
vendor partitions, you want to use them as block
devices to store extents of dynamic partitions, and their by-name symlinks are marked as
/dev/block/platform/soc/10000\.ufshc/by-name/system u:object_r:system_block_device:s0 /dev/block/platform/soc/10000\.ufshc/by-name/vendor u:object_r:system_block_device:s0
Then, add the following line to
typeattribute system_block_device super_block_device_type;
For other configurations, see Implementing dynamic partitions on new devices.
For more information about retrofit updates, see OTA for A/B Devices without Dynamic Partitions.
For a device launching with dynamic partitions support, avoid using userspace fastboot to flash factory images, as booting to userspace is slower than other flashing methods.
To address this,
make dist now builds an additional
super.img image that can be flashed directly to the super
partition. It automatically bundles the contents of logical
partitions, meaning it contains
vendor.img, and so on, in addition to the
partition metadata. This image can be flashed directly to the
super partition without any additional tooling or using
fastbootd. After the build,
super.img is placed in
For A/B devices that launch with dynamic partitions,
super.img contains images in the A slot. After flashing the
super image directly, mark slot A as bootable before rebooting the
For retrofit devices,
make dist builds a set of
super_*.img images that can be flashed directly to
corresponding physical partitions. For example,
BOARD_SUPER_PARTITION_BLOCK_DEVICES is the system
vendor. These images are placed in the OTA folder in