[ASUS ZenFone 8] bnsmb:
How to manually switch the active slot

Switching the active slot on phones with A/B slots is normally only used by the updater to install a new OS update (see https://source.android.com/docs/core/ota/ab for details)

This functionality can also be quite useful if you have two different operating systems on your phone and want to switch between them without reinstalling.

Since the data on all partitions that do not belong to the A/B partitions is used by both operating systems (the one in slot A and the one in slot B), this functionality is limited by the installed operating systems.

The data in most partitions that are only present once should be usable for all operating systems (see here), but this does not apply to the data in the partition that is mounted to /data.

Switching the active slot does work if the OS (including the OS version) installed in slot A and B are equal. It does work most of the time if the OS installed in slot A and B are equal but with different OS versions.

And it should work if the OS installed in slot A and slot B use different directories in /data, e.g. in slot A is a Android based OS installed and in slot B a not on Android based OS (like for example pocketMarketOS)

It does not work (most of the times) if there are different Android distributions in slot A and B: e.g. I did not get it to work if the OS in slot A is the original Android 12 from ASUS and the OS in slot B is OmniROM 12.

(Probably it would work after removing one or more OS related directories from /data but I do not know which - infos on how to use these OS in parallel are welcome)

The instructions below where done on an ASUS Zenfone 8 but I believe they should work with other phones with A/B slots also.

Please note that you should have a working TWRP image for your phone on hand to restore the active slot in case of boot problems.

To get the current slot while the OS is running use the shell command getprop, e.g. execute in a shell on the phone or in an adb shell:

root@ASUS_I006D:/ # getprop ro.boot.slot_suffix
_a
root@ASUS_I006D:/ #

To get the active slot in fastboot mode or while the phone is booted into the bootloader execute on the PC connected to the phone:

sudo fastboot getvar current-slot

There are various methods to manual switch the active slot:

1. Switching the slot using fastboot

Switching the slot via fastboot works if TWRP is installed in the boot partition.

To use it connect the phone to an USB port of the PC and issue these commands on the PC:

# boot the phone into fastboot either if in the bootloader
#
sudo fastboot reboot fastboot

#
# or if the phone is booteind into the recovery or in the normal mode
#
adb reboot fastboot

# wait until the phone is booted in fastboot mode

# get the current slot
#
sudo fastboot getvar current-slot

# change the current slot
#
sudo fastboot set_active b

# check the result
#
sudo fastboot getvar current-slot

# reboot the phone from new current-slot
#
sudo fastboot reboot

Example:

xtrnaw7@t15g /data/develop/android/scripts_on_linux]$ sudo fastboot reboot
Rebooting OKAY [ 0.000s]
Finished. Total time: 0.201s
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$ adb reboot fastboot
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$ sudo fastboot getvar current-slot
current-slot: a
Finished. Total time: 0.001s
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$ sudo fastboot set_active b
Setting current slot to 'b' OKAY [ 0.042s]
Finished. Total time: 0.043s
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$ sudo fastboot getvar current-slot
current-slot: b
Finished. Total time: 0.000s
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$

[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$ sudo fastboot reboot
Rebooting OKAY [ 0.000s]
Finished. Total time: 0.251s

# check the result
#
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$ adb shell getprop ro.boot.slot_suffix
_b
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$

Notes:

Switching the active slot in fastboot mode does not work if the boot image from the original Android 12 from ASUS or from the OmniROM is installed:

[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$ sudo fastboot set_active b
Setting current slot to 'b' FAILED (remote: 'Unable to set slot')
fastboot: error: Command failed
[xtrnaw7@t15g /data/develop/android/scripts_on_linux]$

The same is true it the phone is booted into the bootloader:

[ OmniRomDev - xtrnaw7@t15g /data/develop/android/test ] $ sudo fastboot --set-active=a
Setting current slot to 'a' FAILED (remote: 'Slot Change is not allowed in Lock State')
fastboot: error: Command failed
[ OmniRomDev - xtrnaw7@t15g /data/develop/android/test ] $

Be aware that changing the lock state via

fastboot flashing lock|unlock

will do a factory reset.

2. Switching the slot using TWRP

The active slot for the next reboot can also be changed in the reboot dialog from TWRP.

This can also be done if the phone is booted from the TWRP image.

Note:

This is the fallback to get the phone booting again in case the reboot of the other slot fails for whatever reason.

3. Switching the Slot via Magisk

The active slot can also be changed in the Magisk App. This is used to update the boot partition after an OTA (see here https://topjohnwu.github.io/Magisk/ota.html for details) but can also be used to manual change the active slot.

Open the Magisk App and choose the "install" button to install Magisk into the boot partition. In the next dialog use the method "Install to inactive Slot (After OTA)".

This works also if no update (OTA) was installed and it does not change the Magisk config - it just replaces the Magisk files in the inactive boot partition and activates the inactive boot partition. To reboot the phone then from the now active partition press the "Reboot" button after the update of the boot partition by Magisk is done.

This only works if the OS in both slots is supported by Magisk, of course.

4. Using the binary bootctl

There is binary called bootctl that can be used to switch the active slot. The source code of bootctl is part of the source for the Android OS but as far as I know the binary is not compiled by default and therefor also not installed on the phone.

But there is Magisk module to install the bootctl binary; that Magisk Module can be downloaded from here:

https://github.com/roihershberg/bootctl-binary

Unfortunately the current version of the Magisk Module with bootctl does not install and work out of the box on Android 12 or OmniROM 12 for the ASUS Zenfone 8. Therefor I created a corrected version of the Magisk Module.

The corrected Magisk Module can be downloaded here:

https://bnsmb.de/files/public/Android/bootctl-binary-v2.1.1.zip

The Changelog for the corrected Magisk module for bootctl is:

bootctl must be executed by the root user in a shell on the phone or in an adb shell.

To change the active slot with bootctl use

bootctl set-active-boot-slot SLOT

SLOT is either 0 (for slot A) or 1 (for slot B); the next reboot will then boot from that slot.

To get the active booted slot with bootctl use

bootctl get-current-slot

Notes:

The usage help for bootctl is:

root@ASUS_I006D:# bootctl -h
./bootctl - command-line wrapper for the boot HAL.

Usage:
./bootctl COMMAND

Commands:
hal-info - Show info about boot_control HAL used.
get-number-slots - Prints number of slots.
get-current-slot - Prints currently running SLOT.
mark-boot-successful - Mark current slot as GOOD.
get-active-boot-slot - Prints the SLOT to load on next boot.
set-active-boot-slot SLOT - On next boot, load and execute SLOT.
set-slot-as-unbootable SLOT - Mark SLOT as invalid.
is-slot-bootable SLOT - Returns 0 only if SLOT is bootable.
is-slot-marked-successful SLOT - Returns 0 only if SLOT is marked GOOD.
get-suffix SLOT - Prints suffix for SLOT.
set-snapshot-merge-status STAT - Sets whether a snapshot-merge of any dynamic
partition is in progress. Valid STAT values
are: none, unknown, snapshotted, merging,
or cancelled.
get-snapshot-merge-status - Prints the current snapshot-merge status.

SLOT parameter is the zero-based slot-number.

The source code for bootctl is here:

https://android.googlesource.com/platform/system/extras/+/master/bootctl/bootctl.cpp

https://android.googlesource.com/pl...ware/+/master/include/hardware/boot_control.h

There is also a simple app to change the active slot via the bootctl binary: Switch-My-Slot-Android

Note that the app can only be installed after the Magisk Module for bootctl is installed.

Trouble Shooting

If you get an error like this after rebooting from the previously inactive slot

Cannot load Android System. Your data may be corrupt. if you continue o get this message, you may need to perform a factory data reset and erase all user data storeed on this device

or if the phone boots only in the bootloader after the reboot from the previously inactive slot boot the phone from the TWRP image to activate the previous slot again.

e.g. for the phone ASUS Zenfone 8:

sudo fastboot boot /data/backup/ASUS_ZENFONE8/twrp/twrp-3.6.1_12-1-I006D.img

Then in TWRP select to reboot the phone and in the dialog to reboot switch the slot back to the previous active slot. You can ignore the error messages printed by TWRP after changing the active slot - just continue rebooting the phone.

Note:

On the ASUS Zenfone 8 press the buttons Up, Down, and Power at the same time for about 10 or more seconds to turn off the phone. Afterwards you can boot into the bootloader.

History

06.11.2022 /bs

The section about changing the slot in fastboot mode was not correct: fastboot mode and bootloader mode are differents states of the phone.

06.11.2022 /bs (2)

Switching the slot in fastboot mode does only work if TWRP is installed in the boot partition

12.01.2024 /bs

In TWRP version 3.7.0_12-1 for the ASUS Zenfone 8 the bootctl binary is not included anymore (the bootctl binary is part of the image for TWRP 3.7.0_12-0 and TWRP 3.6.1_12-1).