treewide: bcb: move ab_select command to bcb subcommands

To enhance code organization, it is beneficial to consolidate all A/B
BCB management routines into a single super-command.
The 'bcb' command is an excellent candidate for this purpose.

This patch integrates the separate 'ab_select' command into the 'bcb'
group as the 'ab_select' subcommand, maintaining the same parameter list
for consistency.

Signed-off-by: Dmitry Rokosov <ddrokosov@salutedevices.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Tested-by: Mattijs Korpershoek <mkorpershoek@baylibre.com> # vim3_android
Link: https://lore.kernel.org/r/20241017-android_ab_master-v5-3-43bfcc096d95@salutedevices.com
Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
This commit is contained in:
Dmitry Rokosov
2024-10-17 17:12:08 +03:00
committed by Mattijs Korpershoek
parent a8ca7d46ea
commit b523b4d2c3
18 changed files with 81 additions and 104 deletions

View File

@@ -65,7 +65,6 @@ R: Sam Protsenko <semen.protsenko@linaro.org>
S: Maintained S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-dfu.git T: git https://source.denx.de/u-boot/custodians/u-boot-dfu.git
F: boot/android_ab.c F: boot/android_ab.c
F: cmd/ab_select.c
F: doc/android/ab.rst F: doc/android/ab.rst
F: include/android_ab.h F: include/android_ab.h
F: test/py/tests/test_android/test_ab.py F: test/py/tests/test_android/test_ab.py

View File

@@ -1782,20 +1782,6 @@ config CMD_XXD
endmenu endmenu
menu "Android support commands"
config CMD_AB_SELECT
bool "ab_select"
depends on ANDROID_AB
help
On Android devices with more than one boot slot (multiple copies of
the kernel and system images) this provides a command to select which
slot should be used to boot from and register the boot attempt. This
is used by the new A/B update model where one slot is updated in the
background while running from the other slot.
endmenu
if NET || NET_LWIP if NET || NET_LWIP
menuconfig CMD_NET menuconfig CMD_NET

View File

@@ -17,7 +17,6 @@ obj-$(CONFIG_CMD_2048) += 2048.o
obj-$(CONFIG_CMD_ACPI) += acpi.o obj-$(CONFIG_CMD_ACPI) += acpi.o
obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
obj-$(CONFIG_CMD_AES) += aes.o obj-$(CONFIG_CMD_AES) += aes.o
obj-$(CONFIG_CMD_AB_SELECT) += ab_select.o
obj-$(CONFIG_CMD_ADC) += adc.o obj-$(CONFIG_CMD_ADC) += adc.o
obj-$(CONFIG_CMD_ARMFLASH) += armflash.o obj-$(CONFIG_CMD_ARMFLASH) += armflash.o
obj-$(CONFIG_BLK) += blk_common.o obj-$(CONFIG_BLK) += blk_common.o

View File

@@ -1,66 +0,0 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (C) 2017 The Android Open Source Project
*/
#include <android_ab.h>
#include <command.h>
#include <env.h>
#include <part.h>
static int do_ab_select(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
int ret;
struct blk_desc *dev_desc;
struct disk_partition part_info;
char slot[2];
bool dec_tries = true;
if (argc < 4)
return CMD_RET_USAGE;
for (int i = 4; i < argc; i++) {
if (strcmp(argv[i], "--no-dec") == 0) {
dec_tries = false;
} else {
return CMD_RET_USAGE;
}
}
/* Lookup the "misc" partition from argv[2] and argv[3] */
if (part_get_info_by_dev_and_name_or_num(argv[2], argv[3],
&dev_desc, &part_info,
false) < 0) {
return CMD_RET_FAILURE;
}
ret = ab_select_slot(dev_desc, &part_info, dec_tries);
if (ret < 0) {
printf("Android boot failed, error %d.\n", ret);
return CMD_RET_FAILURE;
}
/* Android standard slot names are 'a', 'b', ... */
slot[0] = BOOT_SLOT_NAME(ret);
slot[1] = '\0';
env_set(argv[1], slot);
printf("ANDROID: Booting slot: %s\n", slot);
return CMD_RET_SUCCESS;
}
U_BOOT_CMD(ab_select, 5, 0, do_ab_select,
"Select the slot used to boot from and register the boot attempt.",
"<slot_var_name> <interface> <dev[:part|#part_name]> [--no-dec]\n"
" - Load the slot metadata from the partition 'part' on\n"
" device type 'interface' instance 'dev' and store the active\n"
" slot in the 'slot_var_name' variable. This also updates the\n"
" Android slot metadata with a boot attempt, which can cause\n"
" successive calls to this function to return a different result\n"
" if the returned slot runs out of boot attempts.\n"
" - If 'part_name' is passed, preceded with a # instead of :, the\n"
" partition name whose label is 'part_name' will be looked up in\n"
" the partition table. This is commonly the \"misc\" partition.\n"
" - If '--no-dec' is set, the number of tries remaining will not\n"
" decremented for the selected boot slot\n"
);

View File

@@ -8,6 +8,7 @@
#include <android_bootloader_message.h> #include <android_bootloader_message.h>
#include <bcb.h> #include <bcb.h>
#include <command.h> #include <command.h>
#include <android_ab.h>
#include <display_options.h> #include <display_options.h>
#include <log.h> #include <log.h>
#include <part.h> #include <part.h>
@@ -376,6 +377,48 @@ void bcb_reset(void)
__bcb_reset(); __bcb_reset();
} }
__maybe_unused static int do_bcb_ab_select(struct cmd_tbl *cmdtp,
int flag, int argc,
char * const argv[])
{
int ret;
struct blk_desc *dev_desc;
struct disk_partition part_info;
char slot[2];
bool dec_tries = true;
if (argc < 4)
return CMD_RET_USAGE;
for (int i = 4; i < argc; i++) {
if (strcmp(argv[i], "--no-dec") == 0)
dec_tries = false;
else
return CMD_RET_USAGE;
}
/* Lookup the "misc" partition from argv[2] and argv[3] */
if (part_get_info_by_dev_and_name_or_num(argv[2], argv[3],
&dev_desc, &part_info,
false) < 0) {
return CMD_RET_FAILURE;
}
ret = ab_select_slot(dev_desc, &part_info, dec_tries);
if (ret < 0) {
printf("Android boot failed, error %d.\n", ret);
return CMD_RET_FAILURE;
}
/* Android standard slot names are 'a', 'b', ... */
slot[0] = BOOT_SLOT_NAME(ret);
slot[1] = '\0';
env_set(argv[1], slot);
printf("ANDROID: Booting slot: %s\n", slot);
return CMD_RET_SUCCESS;
}
U_BOOT_LONGHELP(bcb, U_BOOT_LONGHELP(bcb,
"load <interface> <dev> <part> - load BCB from <interface> <dev>:<part>\n" "load <interface> <dev> <part> - load BCB from <interface> <dev>:<part>\n"
"load <dev> <part> - load BCB from mmc <dev>:<part>\n" "load <dev> <part> - load BCB from mmc <dev>:<part>\n"
@@ -385,6 +428,23 @@ U_BOOT_LONGHELP(bcb,
"bcb dump <field> - dump BCB <field>\n" "bcb dump <field> - dump BCB <field>\n"
"bcb store - store BCB back to <interface>\n" "bcb store - store BCB back to <interface>\n"
"\n" "\n"
#if IS_ENABLED(CONFIG_ANDROID_AB)
"bcb ab_select -\n"
" Select the slot used to boot from and register the boot attempt.\n"
" <slot_var_name> <interface> <dev[:part|#part_name]> [--no-dec]\n"
" - Load the slot metadata from the partition 'part' on\n"
" device type 'interface' instance 'dev' and store the active\n"
" slot in the 'slot_var_name' variable. This also updates the\n"
" Android slot metadata with a boot attempt, which can cause\n"
" successive calls to this function to return a different result\n"
" if the returned slot runs out of boot attempts.\n"
" - If 'part_name' is passed, preceded with a # instead of :, the\n"
" partition name whose label is 'part_name' will be looked up in\n"
" the partition table. This is commonly the \"misc\" partition.\n"
" - If '--no-dec' is set, the number of tries remaining will not\n"
" decremented for the selected boot slot\n"
"\n"
#endif
"Legend:\n" "Legend:\n"
"<interface> - storage device interface (virtio, mmc, etc)\n" "<interface> - storage device interface (virtio, mmc, etc)\n"
"<dev> - storage device index containing the BCB partition\n" "<dev> - storage device index containing the BCB partition\n"
@@ -406,4 +466,7 @@ U_BOOT_CMD_WITH_SUBCMDS(bcb,
U_BOOT_SUBCMD_MKENT(test, 4, 1, do_bcb_test), U_BOOT_SUBCMD_MKENT(test, 4, 1, do_bcb_test),
U_BOOT_SUBCMD_MKENT(dump, 2, 1, do_bcb_dump), U_BOOT_SUBCMD_MKENT(dump, 2, 1, do_bcb_dump),
U_BOOT_SUBCMD_MKENT(store, 1, 1, do_bcb_store), U_BOOT_SUBCMD_MKENT(store, 1, 1, do_bcb_store),
#if IS_ENABLED(CONFIG_ANDROID_AB)
U_BOOT_SUBCMD_MKENT(ab_select, 5, 1, do_bcb_ab_select),
#endif
); );

View File

@@ -48,7 +48,6 @@ CONFIG_CMD_SPL=y
CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
CONFIG_CMD_BCB=y CONFIG_CMD_BCB=y
# CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_AB_SELECT=y
CONFIG_BOOTP_DNS2=y CONFIG_BOOTP_DNS2=y
# CONFIG_CMD_PMIC is not set # CONFIG_CMD_PMIC is not set
CONFIG_CMD_AVB=y CONFIG_CMD_AVB=y

View File

@@ -44,7 +44,6 @@ CONFIG_CMD_ADTIMG=y
CONFIG_CMD_ABOOTIMG=y CONFIG_CMD_ABOOTIMG=y
CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
CONFIG_CMD_BCB=y CONFIG_CMD_BCB=y
CONFIG_CMD_AB_SELECT=y
CONFIG_BOOTP_DNS2=y CONFIG_BOOTP_DNS2=y
# CONFIG_CMD_PMIC is not set # CONFIG_CMD_PMIC is not set
CONFIG_CMD_AVB=y CONFIG_CMD_AVB=y

View File

@@ -46,7 +46,6 @@ CONFIG_CMD_ADTIMG=y
CONFIG_CMD_ABOOTIMG=y CONFIG_CMD_ABOOTIMG=y
CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2 CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
CONFIG_CMD_BCB=y CONFIG_CMD_BCB=y
CONFIG_CMD_AB_SELECT=y
CONFIG_BOOTP_DNS2=y CONFIG_BOOTP_DNS2=y
# CONFIG_CMD_PMIC is not set # CONFIG_CMD_PMIC is not set
CONFIG_CMD_AVB=y CONFIG_CMD_AVB=y

View File

@@ -47,7 +47,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_AB_SELECT=y
CONFIG_CMD_REGULATOR=y CONFIG_CMD_REGULATOR=y
CONFIG_CMD_AVB=y CONFIG_CMD_AVB=y
CONFIG_OF_CONTROL=y CONFIG_OF_CONTROL=y

View File

@@ -47,7 +47,6 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_AB_SELECT=y
CONFIG_CMD_REGULATOR=y CONFIG_CMD_REGULATOR=y
CONFIG_CMD_AVB=y CONFIG_CMD_AVB=y
CONFIG_OF_CONTROL=y CONFIG_OF_CONTROL=y

View File

@@ -27,6 +27,7 @@ CONFIG_CONSOLE_RECORD=y
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000 CONFIG_CONSOLE_RECORD_OUT_SIZE=0x6000
CONFIG_PRE_CONSOLE_BUFFER=y CONFIG_PRE_CONSOLE_BUFFER=y
CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_ANDROID_AB=y
CONFIG_CMD_CPU=y CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y CONFIG_CMD_BOOTZ=y
@@ -46,6 +47,7 @@ CONFIG_CMD_MD5SUM=y
CONFIG_CMD_MEMINFO=y CONFIG_CMD_MEMINFO=y
CONFIG_CMD_MX_CYCLIC=y CONFIG_CMD_MX_CYCLIC=y
CONFIG_CMD_MEMTEST=y CONFIG_CMD_MEMTEST=y
CONFIG_CMD_BCB=y
CONFIG_CMD_CLK=y CONFIG_CMD_CLK=y
CONFIG_CMD_DEMO=y CONFIG_CMD_DEMO=y
CONFIG_CMD_GPIO=y CONFIG_CMD_GPIO=y

View File

@@ -103,7 +103,6 @@ CONFIG_CMD_AXI=y
CONFIG_CMD_CAT=y CONFIG_CMD_CAT=y
CONFIG_CMD_SETEXPR_FMT=y CONFIG_CMD_SETEXPR_FMT=y
CONFIG_CMD_XXD=y CONFIG_CMD_XXD=y
CONFIG_CMD_AB_SELECT=y
CONFIG_CMD_DHCP6=y CONFIG_CMD_DHCP6=y
CONFIG_BOOTP_DNS2=y CONFIG_BOOTP_DNS2=y
CONFIG_CMD_PCAP=y CONFIG_CMD_PCAP=y

View File

@@ -18,7 +18,7 @@ The A/B updates support can be activated by specifying next options in
your board configuration file:: your board configuration file::
CONFIG_ANDROID_AB=y CONFIG_ANDROID_AB=y
CONFIG_CMD_AB_SELECT=y CONFIG_CMD_BCB=y
The disk space on target device must be partitioned in a way so that each The disk space on target device must be partitioned in a way so that each
partition which needs to be updated has two or more instances. The name of partition which needs to be updated has two or more instances. The name of
@@ -26,8 +26,8 @@ each instance must be formed by adding suffixes: ``_a``, ``_b``, ``_c``, etc.
For example: ``boot_a``, ``boot_b``, ``system_a``, ``system_b``, ``vendor_a``, For example: ``boot_a``, ``boot_b``, ``system_a``, ``system_b``, ``vendor_a``,
``vendor_b``. ``vendor_b``.
As a result you can use ``ab_select`` command to ensure A/B boot process in your As a result you can use ``bcb ab_select`` command to ensure A/B boot process in
boot script. This command analyzes and processes A/B metadata stored on a your boot script. This command analyzes and processes A/B metadata stored on a
special partition (e.g. ``misc``) and determines which slot should be used for special partition (e.g. ``misc``) and determines which slot should be used for
booting up. booting up.
@@ -42,15 +42,15 @@ Command usage
.. code-block:: none .. code-block:: none
ab_select <slot_var_name> <interface> <dev[:part_number|#part_name]> bcb ab_select <slot_var_name> <interface> <dev[:part_number|#part_name]>
for example:: for example::
=> ab_select slot_name mmc 1:4 => bcb ab_select slot_name mmc 1:4
or:: or::
=> ab_select slot_name mmc 1#misc => bcb ab_select slot_name mmc 1#misc
Result:: Result::

View File

@@ -12,7 +12,7 @@
#define LOGO_UUID "43a3305d-150f-4cc9-bd3b-38fca8693846;" #define LOGO_UUID "43a3305d-150f-4cc9-bd3b-38fca8693846;"
#define ROOT_UUID "ddb8c3f6-d94d-4394-b633-3134139cc2e0;" #define ROOT_UUID "ddb8c3f6-d94d-4394-b633-3134139cc2e0;"
#if defined(CONFIG_CMD_AB_SELECT) #if defined(CONFIG_CMD_BCB) && defined(CONFIG_ANDROID_AB)
#define PARTS_DEFAULT \ #define PARTS_DEFAULT \
"uuid_disk=${uuid_gpt_disk};" \ "uuid_disk=${uuid_gpt_disk};" \
"name=logo,start=512K,size=2M,uuid=" LOGO_UUID \ "name=logo,start=512K,size=2M,uuid=" LOGO_UUID \

View File

@@ -12,7 +12,7 @@
#define LOGO_UUID "43a3305d-150f-4cc9-bd3b-38fca8693846;" #define LOGO_UUID "43a3305d-150f-4cc9-bd3b-38fca8693846;"
#define ROOT_UUID "ddb8c3f6-d94d-4394-b633-3134139cc2e0;" #define ROOT_UUID "ddb8c3f6-d94d-4394-b633-3134139cc2e0;"
#if defined(CONFIG_CMD_AB_SELECT) #if defined(CONFIG_CMD_BCB) && defined(CONFIG_ANDROID_AB)
#define PARTS_DEFAULT \ #define PARTS_DEFAULT \
"uuid_disk=${uuid_gpt_disk};" \ "uuid_disk=${uuid_gpt_disk};" \
"name=logo,start=512K,size=2M,uuid=" LOGO_UUID \ "name=logo,start=512K,size=2M,uuid=" LOGO_UUID \

View File

@@ -47,13 +47,13 @@
#define AVB_VERIFY_CMD "" #define AVB_VERIFY_CMD ""
#endif #endif
#if defined(CONFIG_CMD_AB_SELECT) #if defined(CONFIG_CMD_BCB) && defined(CONFIG_ANDROID_AB)
#define ANDROIDBOOT_GET_CURRENT_SLOT_CMD "get_current_slot=" \ #define ANDROIDBOOT_GET_CURRENT_SLOT_CMD "get_current_slot=" \
"if part number mmc ${mmcdev} " CONTROL_PARTITION " control_part_number; " \ "if part number mmc ${mmcdev} " CONTROL_PARTITION " control_part_number; " \
"then " \ "then " \
"echo " CONTROL_PARTITION \ "echo " CONTROL_PARTITION \
" partition number:${control_part_number};" \ " partition number:${control_part_number};" \
"ab_select current_slot mmc ${mmcdev}:${control_part_number};" \ "bcb ab_select current_slot mmc ${mmcdev}:${control_part_number};" \
"else " \ "else " \
"echo " CONTROL_PARTITION " partition not found;" \ "echo " CONTROL_PARTITION " partition not found;" \
"fi;\0" "fi;\0"

View File

@@ -93,13 +93,13 @@
#define CONTROL_PARTITION "misc" #define CONTROL_PARTITION "misc"
#if defined(CONFIG_CMD_AB_SELECT) #if defined(CONFIG_CMD_BCB) && defined(CONFIG_ANDROID_AB)
#define AB_SELECT_SLOT \ #define AB_SELECT_SLOT \
"if part number mmc 1 " CONTROL_PARTITION " control_part_number; " \ "if part number mmc 1 " CONTROL_PARTITION " control_part_number; " \
"then " \ "then " \
"echo " CONTROL_PARTITION \ "echo " CONTROL_PARTITION \
" partition number:${control_part_number};" \ " partition number:${control_part_number};" \
"ab_select slot_name mmc ${mmcdev}:${control_part_number};" \ "bcb ab_select slot_name mmc ${mmcdev}:${control_part_number};" \
"else " \ "else " \
"echo " CONTROL_PARTITION " partition not found;" \ "echo " CONTROL_PARTITION " partition not found;" \
"exit;" \ "exit;" \

View File

@@ -56,20 +56,20 @@ def ab_disk_image(u_boot_console):
@pytest.mark.boardspec('sandbox') @pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('android_ab') @pytest.mark.buildconfigspec('android_ab')
@pytest.mark.buildconfigspec('cmd_ab_select') @pytest.mark.buildconfigspec('cmd_bcb')
@pytest.mark.requiredtool('sgdisk') @pytest.mark.requiredtool('sgdisk')
def test_ab(ab_disk_image, u_boot_console): def test_ab(ab_disk_image, u_boot_console):
"""Test the 'ab_select' command.""" """Test the 'bcb ab_select' command."""
u_boot_console.run_command('host bind 0 ' + ab_disk_image.path) u_boot_console.run_command('host bind 0 ' + ab_disk_image.path)
output = u_boot_console.run_command('ab_select slot_name host 0#misc') output = u_boot_console.run_command('bcb ab_select slot_name host 0#misc')
assert 're-initializing A/B metadata' in output assert 're-initializing A/B metadata' in output
assert 'Attempting slot a, tries remaining 7' in output assert 'Attempting slot a, tries remaining 7' in output
output = u_boot_console.run_command('printenv slot_name') output = u_boot_console.run_command('printenv slot_name')
assert 'slot_name=a' in output assert 'slot_name=a' in output
output = u_boot_console.run_command('ab_select slot_name host 0:1') output = u_boot_console.run_command('bcb ab_select slot_name host 0:1')
assert 'Attempting slot b, tries remaining 7' in output assert 'Attempting slot b, tries remaining 7' in output
output = u_boot_console.run_command('printenv slot_name') output = u_boot_console.run_command('printenv slot_name')
assert 'slot_name=b' in output assert 'slot_name=b' in output