[Android Software Development] Dees_Troy:
TWRP and A/B devices:

From a TWRP standpoint, A/B devices aren't a whole lot different from regular devices, but developers seem to be shy about working on these devices. I'm going to try to shed some light on this subject and hopefully this will serve as a guide for porting TWRP to A/B devices.

Firstly, let's understand what is an A/B device and how it's different. A/B devices have duplicates of many partitions on the device. An A/B device has 2x system partitions, 2x boot partitions, 2x vendor partitions, 2x modem / firmware partitions, etc. Only one slot is in use at a time. During early boot, the first stages of the bootloader read some small amount of data called the BCB or Bootloader Control Block and decide whether to boot the A partitions or the B partitions. When an OTA update is available, the data from the active slot is copied from the inactive slot and patched / updated. For example, if you're currently on slot A, your device would download the update and copy the existing system partition from slot A and patch / update it with the new updates into slot B. Once the copying and updating is complete, the BCB is updated and the device reboots using slot B. Next time an update is available, the system partition in slot B is copied to slot A and updated, the BCB gets updated, and we reboot to slot A. When viewing partitions on the device, you'll see something like this:

/dev/block/bootdevice/by-name/boot_a
/dev/block/bootdevice/by-name/boot_b
/dev/block/bootdevice/by-name/system_a
/dev/block/bootdevice/by-name/system_b
/dev/block/bootdevice/by-name/userdata
/dev/block/bootdevice/by-name/vendor_a
/dev/block/bootdevice/by-name/vendor_b

Note the dual boot, system and vendor partitions in the list above, but only one userdata partition.

While there is technically no requirement that I am aware of, all A/B devices shipped thus far have no separate recovery partition. Instead, the boot image contains the recovery in its ramdisk. The important thing is knowing that the boot image now also contains the recovery. For completeness, the system partition is a full root file system. During boot, if the kernel is told to boot to recovery, it will extract the ramdisk in the boot partition. If the kernel is not told by the bootloader to boot to recovery, then the kernel will mount the appropriate system partition (A or B) because the system partition is a full root file system. This means that the system partition on these devices is mounted to / instead of to /system and the system partition contains all of the files that would have normally been in the boot image ramdisk and a /system subfolder.

From a TWRP standpoint, there are 3 things that you have to do for an A/B device. First, you need to set

AB_OTA_UPDATER := true

in your BoardConfig.mk. Secondly, for any partition that has an A/B option, you need to add

flags=slotselect

in your fstab so something like this:

/boot	emmc	/dev/block/bootdevice/by-name/boot	flags=slotselect
/system	ext4	/dev/block/bootdevice/by-name/system	flags=slotselect
/system_image	emmc	/dev/block/bootdevice/by-name/system	flags=slotselect
/vendor	ext4	/dev/block/bootdevice/by-name/vendor	flags=slotselect;display="Vendor";backup=1
/vendor_image	emmc	/dev/block/bootdevice/by-name/vendor	flags=slotselect

Lastly, once you get into TWRP, you will probably want to make sure that bootctl hal-info responds correctly with no errors. Usually the bootctl binary requires a proprietary library or even a couple of services to work correctly. If bootctl does not work correctly, then you will not be able to switch slots within TWRP correctly either.

In addition to setting

AB_OTA_UPDATER := true

you may also want to set:

BOARD_USES_RECOVERY_AS_BOOT := true
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true

If you set

BOARD_USES_RECOVERY_AS_BOOT := true

then make recoveryimage will no longer work and instead you will have to make bootimage. I don't recommend setting either of these flags for TWRP-only build trees. These flags will probably be required for developers building full ROMs for A/B devices.

Installing / Flashing TWRP on A/B devices:

Since all known A/B devices do not have a separate recovery partition, you will eventually have to flash TWRP to the boot partition. On the Pixel 1 and 2, we use fastboot boot to temporarily boot TWRP without flashing TWRP. We are then supplying a zip to allow users to flash TWRP to both slots. You can download one of these zips from our website and update the zip as needed to support your devices. Eventually we will add tools to TWRP to allow users to flash recoveries on these devices without needing to use zips.

Recently, I worked on the Razer Phone. The Razer Phone unfortunately does not support fastboot boot. Instead, users have to determine their currently active boot slot using

adb shell getprop ro.boot.slot_suffix

then use

fastboot --set-active=_a

to switch slots to the inactive slot. From here, the user can

fastboot flash boot twrp.img && fastboot reboot

to get into TWRP. Once in TWRP they can then go to the reboot page and change back to their originally active slot, make a backup, then install TWRP. Using the inactive slot allows users to get a good, unmodified backup of their device before installing TWRP.

Hopefully this helps!

Debugging with gdb in TWRP guide can be found here!