Android dynamic partitions
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.
The standard installation process for internal storage would be to flash a root filesystem to a GPT-based partition, by default
system. On devices with dynamic partitions, either there isn't a GPT system partition, or in the case of retrofit, the flashing interface prevents flashing to the GPT system partition without command line options like
Devices with dynamic partitions either need to have a different GPT partition flashed (like super or userdata) or a way to understand the dynamic partitions and map them to logical block devices so they can be mounted. PostmarketOS depends on the configuration of the device specific package to find and map the dynamic partitions so there might be no support for dynamic partitions on some devices.
- 1 Different options of installation
- 2 Adding support for dynamic partitions to your port
- 3 See also
Different options of installation
There are a few ways to install the rootfs to a device with dynamic partitions. While some device pages don't document both, the first two methods do not need device-specific modifications.
Flashing to userdata
One location for the rootfs 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. It also lets you make use of most of your device's storage.
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), Volla Phone 22 (volla-mimameid). Some devices are configured to automatically do this.
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
(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
Another method is to flash to the dynamic partitions in fastbootd. The disadvantages of this are that it might be a source of issues because of the extra code needed to support dynamic partitions, and that fastbootd is needed for a flashing interface (which does not support booting even if the bootloader might, and might get erased when flashing).
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
Afterwards, you can flash the rootfs as normal.
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.
One way to do this is to keep an Android(-like) installation on one slot, if your device has A/B partitions:
$ fastboot set_active b # Either slot is fine if they both have Android 10+ $ fastboot reboot fastboot $ fastboot set_active a # Avoid overwriting fastbootd by switching to the inactive slot $ pmbootstrap flasher flash_rootfs $ pmbootstrap flasher flash_kernel
Adding support for dynamic partitions to your port
There are a few changes you need to make to the device package:
make-dynpart-mappingsto the dependencies in the APKBUILD
deviceinfo_super_partitionsin 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.
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).
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+
Devices launching with Android 10 (or later) 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
The same information is available in postmarketOS under
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"