Android dynamic partitions

From postmarketOS
Jump to navigation Jump to search

Devices running Android 10 and later versions implement the dynamic partitioning scheme. With dynamic partitioning, multiple logical partitions are defined in a single "super" partition. They behave very much like Linux LVM, being flexible and easy to change around. However, dynamic partitioning follows a different format from LVM.

PostmarketOS does not support dynamic partitioning out of the box, but it can through some changes to the device specific package.

Different options of installation

TODO To limit the effect of device differentiation, each device should ideally be compatible with all flashing and installation methods. The first two do not need device-specific modifications but the last does.

There are currently three ways to install the rootfs to a device with dynamic partitions. Each method has some disadvantage.

Flashing to userdata

One location is the userdata partition. As the name implies, this will overwrite the existing data (things like apps, photos, videos, etc.) on your device like a factory reset. If you have any important data on your device and haven't done so already, you should definitely back up important data at this point.

This has been used by the SHIFT6mq.

Flashing to userdata is documented here.

Flashing to super

Another option is overwriting the super partition, or the partition that stores and defines the dynamic partitions. Depending on whether your device launched with at least Android 10 (non-retrofit) or not (retrofit), you might find your device unusable with Android unless you back up the super partition.

This is used by the OnePlus 8T (oneplus-kebab), OnePlus 9 & 9 Pro (oneplus-lemonade & oneplus-lemonadep), Xiaomi Mi Pad 5 Pro (xiaomi-elish), Xiaomi Poco M2 (xiaomi-shiva).

From the oneplus-kebab device page, back up your super partition like so (if your device is retrofit, replace "super" with "system"):

   $ adb pull /dev/block/by-name/super super.img

Then, you can either flash to super if your device is non-retrofit:

   $ pmbootstrap flasher flash_rootfs --partition super

or force flash if your device is retrofit:

   $ pmbootstrap export
   $ fastboot flash system --force /tmp/postmarketOS-export/(device codename).img

where (device codename) is the codename of the device.

To go back to Android, you can flash the backed up super partition (again, if your device is retrofit, replace super with system):

   $ fastboot flash super super.img

make-dynpart-mappings

The most recent method is to flash to the dynamic partitions in fastbootd. The disadvantage of this is that it uses custom code that is not used by Android and started development in April 2022.

The bulk of this page documents how to do this.

Adding support for dynamic partitions to your port

There are a few changes you need to make to the device package:

  • add make-dynpart-mappings to the dependencies in the APKBUILD
  • set deviceinfo_super_partitions in deviceinfo to a certain value
  • regenerate the checksums
  • rebuild the device package and everything related to updating it

There is no single correct value for deviceinfo_super_partitions, hence the need for it as a configuration value. Below is a guide to determine the appropriate value for deviceinfo_super_partitions.

Retrofit or single super partition?

The super partitions are different for devices that launched before Android 10, called retrofit devices, and devices launching with Android 10 or higher.

Retrofit Devices

For retrofit devices, old A/B partitions are re-purposed into a single "virtual" super partition, usually the system_a, system_b, vendor_a, vendor_p and product partitions, but it can vary between devices. Which partitions are used is specified in the BOARD_SUPER_PARTITION_BLOCK_DEVICES variable in the devices BoardConfig*.mk but you only need to specify the partitions with the metadata (see below).

Special cases

On retrofit devices, the device manufacturer has the option to specify different super partitions. If your device has a https://github.com/LineageOS/android_device_* repository, you can look for the value of BOARD_SUPER_PARTITION_METADATA_DEVICE in the board configuration (i.e. BoardConfig*.mk). If it is unspecified, then it is probably "system", otherwise you can use the value you found. It can also be found on the kernel command line, as the argument to the option "androidboot.super_partition". You may need to add both slot suffixes and find each physical partition (e.g. "system_a" and "system_b").

Devices launching with Android 10

For devices launching with Android 10 have a single super partition called "super". If your device has A/B seamless update, or you are not sure, then you should specify the same super partition twice.

Finding the device nodes

On Android, there are symlinks to the appropriate device nodes in /dev/block/by-name/. You can use the adb root shell to find the device node names of your super partitions:

$ adb root
$ adb shell
(device hostname):/# readlink /dev/block/by-name/super | basename
mmcblk0p127
(device hostname):/# readlink /dev/block/by-name/system_a | basename
mmcblk0p68
(device hostname):/# readlink /dev/block/by-name/system_b | basename
mmcblk0p69
(device hostname):/# exit

You can then use the output to determine the appropriate value of deviceinfo_super_partitions by prepending /dev/ to each partition:

# for a retrofit device
deviceinfo_super_partitions="/dev/mmcblk0p68 /dev/mmcblk0p69"
# for a device with the single super partition
deviceinfo_super_partitions="/dev/mmcblk0p127 /dev/mmcblk0p127"

Flashing to dynamic partitions

Dynamic partitions are only supposed to be flashed in fastbootd, as opposed to the bootloader fastboot. To get to fastbootd from the bootloader fastboot, run:

$ fastboot reboot fastboot

Preserving fastbootd

Since fastbootd is in userspace, you should have a recovery (custom or Android stock recovery) ready, either on the target device, or on the device responsible for flashing. If your device stores the recovery on the boot partition, then fastbootd will be overwritten when you flash the pmOS kernel. You could try to preserve the boot partition of one of the slots on the device or flash a recovery image every time you want to modify the dynamic partitions.

See also