mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-24 14:25:56 +00:00
bootstd: Add test for bootmeth_android
Add a unit test for testing the Android bootmethod. This requires another mmc image (mmc7) to contain the following partitions: - misc: contains the Bootloader Control Block (BCB) - boot_a: contains a fake generic kernel image - vendor_boot_a: contains a fake vendor_boot image Also add BOOTMETH_ANDROID as a dependency on sandbox so that we can test this with: $ ./test/py/test.py --bd sandbox --build -k test_ut # build the mmc7.img $ ./test/py/test.py --bd sandbox --build -k bootflow_android Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com> Reviewed-by: Julien Masson <jmasson@baylibre.com> Reviewed-by: Guillaume La Roque <glaroque@baylibre.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
125d9f3306
commit
c2a2a06e01
4 changed files with 153 additions and 4 deletions
|
@ -43,6 +43,7 @@
|
||||||
mmc4 = "/mmc4";
|
mmc4 = "/mmc4";
|
||||||
mmc5 = "/mmc5";
|
mmc5 = "/mmc5";
|
||||||
mmc6 = "/mmc6";
|
mmc6 = "/mmc6";
|
||||||
|
mmc7 = "/mmc7";
|
||||||
pci0 = &pci0;
|
pci0 = &pci0;
|
||||||
pci1 = &pci1;
|
pci1 = &pci1;
|
||||||
pci2 = &pci2;
|
pci2 = &pci2;
|
||||||
|
@ -1129,6 +1130,13 @@
|
||||||
filename = "mmc6.img";
|
filename = "mmc6.img";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This is used for Android tests */
|
||||||
|
mmc7 {
|
||||||
|
status = "disabled";
|
||||||
|
compatible = "sandbox,mmc";
|
||||||
|
filename = "mmc7.img";
|
||||||
|
};
|
||||||
|
|
||||||
pch {
|
pch {
|
||||||
compatible = "sandbox,pch";
|
compatible = "sandbox,pch";
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ CONFIG_FIT=y
|
||||||
CONFIG_FIT_RSASSA_PSS=y
|
CONFIG_FIT_RSASSA_PSS=y
|
||||||
CONFIG_FIT_CIPHER=y
|
CONFIG_FIT_CIPHER=y
|
||||||
CONFIG_FIT_VERBOSE=y
|
CONFIG_FIT_VERBOSE=y
|
||||||
|
CONFIG_BOOTMETH_ANDROID=y
|
||||||
CONFIG_LEGACY_IMAGE_FORMAT=y
|
CONFIG_LEGACY_IMAGE_FORMAT=y
|
||||||
CONFIG_MEASURED_BOOT=y
|
CONFIG_MEASURED_BOOT=y
|
||||||
CONFIG_BOOTSTAGE=y
|
CONFIG_BOOTSTAGE=y
|
||||||
|
@ -40,7 +41,6 @@ CONFIG_LOG_MAX_LEVEL=9
|
||||||
CONFIG_LOG_DEFAULT_LEVEL=6
|
CONFIG_LOG_DEFAULT_LEVEL=6
|
||||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||||
CONFIG_STACKPROTECTOR=y
|
CONFIG_STACKPROTECTOR=y
|
||||||
CONFIG_ANDROID_AB=y
|
|
||||||
CONFIG_CMD_CPU=y
|
CONFIG_CMD_CPU=y
|
||||||
CONFIG_CMD_LICENSE=y
|
CONFIG_CMD_LICENSE=y
|
||||||
CONFIG_CMD_SMBIOS=y
|
CONFIG_CMD_SMBIOS=y
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
|
extern U_BOOT_DRIVER(bootmeth_android);
|
||||||
extern U_BOOT_DRIVER(bootmeth_cros);
|
extern U_BOOT_DRIVER(bootmeth_cros);
|
||||||
extern U_BOOT_DRIVER(bootmeth_2script);
|
extern U_BOOT_DRIVER(bootmeth_2script);
|
||||||
|
|
||||||
|
@ -518,12 +519,12 @@ BOOTSTD_TEST(bootflow_cmd_boot, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
|
||||||
* @uts: Unit test state
|
* @uts: Unit test state
|
||||||
* @mmc_dev: MMC device to use, e.g. "mmc4". Note that this must remain valid
|
* @mmc_dev: MMC device to use, e.g. "mmc4". Note that this must remain valid
|
||||||
* in the caller until
|
* in the caller until
|
||||||
* @bind_cros: true to bind the ChromiumOS bootmeth
|
* @bind_cros: true to bind the ChromiumOS and Android bootmeths
|
||||||
* @old_orderp: Returns the original bootdev order, which must be restored
|
* @old_orderp: Returns the original bootdev order, which must be restored
|
||||||
* Returns 0 on success, -ve on failure
|
* Returns 0 on success, -ve on failure
|
||||||
*/
|
*/
|
||||||
static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
|
static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
|
||||||
bool bind_cros, const char ***old_orderp)
|
bool bind_cros_android, const char ***old_orderp)
|
||||||
{
|
{
|
||||||
static const char *order[] = {"mmc2", "mmc1", NULL, NULL};
|
static const char *order[] = {"mmc2", "mmc1", NULL, NULL};
|
||||||
struct udevice *dev, *bootstd;
|
struct udevice *dev, *bootstd;
|
||||||
|
@ -545,12 +546,19 @@ static int prep_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
|
||||||
"bootmeth_script", 0, ofnode_null(), &dev));
|
"bootmeth_script", 0, ofnode_null(), &dev));
|
||||||
|
|
||||||
/* Enable the cros bootmeth if needed */
|
/* Enable the cros bootmeth if needed */
|
||||||
if (IS_ENABLED(CONFIG_BOOTMETH_CROS) && bind_cros) {
|
if (IS_ENABLED(CONFIG_BOOTMETH_CROS) && bind_cros_android) {
|
||||||
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
|
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
|
||||||
ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_cros),
|
ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_cros),
|
||||||
"cros", 0, ofnode_null(), &dev));
|
"cros", 0, ofnode_null(), &dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enable the android bootmeths if needed */
|
||||||
|
if (IS_ENABLED(CONFIG_BOOTMETH_ANDROID) && bind_cros_android) {
|
||||||
|
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
|
||||||
|
ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_android),
|
||||||
|
"android", 0, ofnode_null(), &dev));
|
||||||
|
}
|
||||||
|
|
||||||
/* Change the order to include the device */
|
/* Change the order to include the device */
|
||||||
std = dev_get_priv(bootstd);
|
std = dev_get_priv(bootstd);
|
||||||
old_order = std->bootdev_order;
|
old_order = std->bootdev_order;
|
||||||
|
@ -589,6 +597,37 @@ static int scan_mmc_bootdev(struct unit_test_state *uts, const char *mmc_dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scan_mmc_android_bootdev() - Set up an mmc bootdev so we can access other
|
||||||
|
* distros. Android bootflow might print "ANDROID:*" while scanning
|
||||||
|
*
|
||||||
|
* @uts: Unit test state
|
||||||
|
* @mmc_dev: MMC device to use, e.g. "mmc4"
|
||||||
|
* Returns 0 on success, -ve on failure
|
||||||
|
*/
|
||||||
|
static int scan_mmc_android_bootdev(struct unit_test_state *uts, const char *mmc_dev)
|
||||||
|
{
|
||||||
|
struct bootstd_priv *std;
|
||||||
|
struct udevice *bootstd;
|
||||||
|
const char **old_order;
|
||||||
|
|
||||||
|
ut_assertok(prep_mmc_bootdev(uts, mmc_dev, true, &old_order));
|
||||||
|
|
||||||
|
console_record_reset_enable();
|
||||||
|
ut_assertok(run_command("bootflow scan", 0));
|
||||||
|
/* Android bootflow might print one or two 'ANDROID:*' logs */
|
||||||
|
ut_check_skipline(uts);
|
||||||
|
ut_check_skipline(uts);
|
||||||
|
ut_assert_console_end();
|
||||||
|
|
||||||
|
/* Restore the order used by the device tree */
|
||||||
|
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
|
||||||
|
std = dev_get_priv(bootstd);
|
||||||
|
std->bootdev_order = old_order;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scan_mmc4_bootdev() - Set up the mmc4 bootdev so we can access a fake Armbian
|
* scan_mmc4_bootdev() - Set up the mmc4 bootdev so we can access a fake Armbian
|
||||||
*
|
*
|
||||||
|
@ -1160,3 +1199,26 @@ static int bootflow_cros(struct unit_test_state *uts)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
BOOTSTD_TEST(bootflow_cros, 0);
|
BOOTSTD_TEST(bootflow_cros, 0);
|
||||||
|
|
||||||
|
/* Test Android bootmeth */
|
||||||
|
static int bootflow_android(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
if (!IS_ENABLED(CONFIG_BOOTMETH_ANDROID))
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
ut_assertok(scan_mmc_android_bootdev(uts, "mmc7"));
|
||||||
|
ut_assertok(run_command("bootflow list", 0));
|
||||||
|
|
||||||
|
ut_assert_nextlinen("Showing all");
|
||||||
|
ut_assert_nextlinen("Seq");
|
||||||
|
ut_assert_nextlinen("---");
|
||||||
|
ut_assert_nextlinen(" 0 extlinux");
|
||||||
|
ut_assert_nextlinen(" 1 android ready mmc 0 mmc7.bootdev.whole ");
|
||||||
|
ut_assert_nextlinen("---");
|
||||||
|
ut_assert_skip_to_line("(2 bootflows, 2 valid)");
|
||||||
|
|
||||||
|
ut_assert_console_end();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
BOOTSTD_TEST(bootflow_android, 0);
|
||||||
|
|
|
@ -11,6 +11,7 @@ import pytest
|
||||||
import u_boot_utils
|
import u_boot_utils
|
||||||
# pylint: disable=E0611
|
# pylint: disable=E0611
|
||||||
from tests import fs_helper
|
from tests import fs_helper
|
||||||
|
from test_android import test_abootimg
|
||||||
|
|
||||||
def mkdir_cond(dirname):
|
def mkdir_cond(dirname):
|
||||||
"""Create a directory if it doesn't already exist
|
"""Create a directory if it doesn't already exist
|
||||||
|
@ -423,6 +424,83 @@ def setup_cros_image(cons):
|
||||||
|
|
||||||
return fname
|
return fname
|
||||||
|
|
||||||
|
def setup_android_image(cons):
|
||||||
|
"""Create a 20MB disk image with Android partitions"""
|
||||||
|
Partition = collections.namedtuple('part', 'start,size,name')
|
||||||
|
parts = {}
|
||||||
|
disk_data = None
|
||||||
|
|
||||||
|
def set_part_data(partnum, data):
|
||||||
|
"""Set the contents of a disk partition
|
||||||
|
|
||||||
|
This updates disk_data by putting data in the right place
|
||||||
|
|
||||||
|
Args:
|
||||||
|
partnum (int): Partition number to set
|
||||||
|
data (bytes): Data for that partition
|
||||||
|
"""
|
||||||
|
nonlocal disk_data
|
||||||
|
|
||||||
|
start = parts[partnum].start * sect_size
|
||||||
|
disk_data = disk_data[:start] + data + disk_data[start + len(data):]
|
||||||
|
|
||||||
|
mmc_dev = 7
|
||||||
|
fname = os.path.join(cons.config.source_dir, f'mmc{mmc_dev}.img')
|
||||||
|
u_boot_utils.run_and_log(cons, 'qemu-img create %s 20M' % fname)
|
||||||
|
u_boot_utils.run_and_log(cons, f'cgpt create {fname}')
|
||||||
|
|
||||||
|
ptr = 40
|
||||||
|
|
||||||
|
# Number of sectors in 1MB
|
||||||
|
sect_size = 512
|
||||||
|
sect_1mb = (1 << 20) // sect_size
|
||||||
|
|
||||||
|
required_parts = [
|
||||||
|
{'num': 1, 'label':'misc', 'size': '1M'},
|
||||||
|
{'num': 2, 'label':'boot_a', 'size': '4M'},
|
||||||
|
{'num': 3, 'label':'boot_b', 'size': '4M'},
|
||||||
|
{'num': 4, 'label':'vendor_boot_a', 'size': '4M'},
|
||||||
|
{'num': 5, 'label':'vendor_boot_b', 'size': '4M'},
|
||||||
|
]
|
||||||
|
|
||||||
|
for part in required_parts:
|
||||||
|
size_str = part['size']
|
||||||
|
if 'M' in size_str:
|
||||||
|
size = int(size_str[:-1]) * sect_1mb
|
||||||
|
else:
|
||||||
|
size = int(size_str)
|
||||||
|
u_boot_utils.run_and_log(
|
||||||
|
cons,
|
||||||
|
f"cgpt add -i {part['num']} -b {ptr} -s {size} -l {part['label']} -t basicdata {fname}")
|
||||||
|
ptr += size
|
||||||
|
|
||||||
|
u_boot_utils.run_and_log(cons, f'cgpt boot -p {fname}')
|
||||||
|
out = u_boot_utils.run_and_log(cons, f'cgpt show -q {fname}')
|
||||||
|
|
||||||
|
# Create a dict (indexed by partition number) containing the above info
|
||||||
|
for line in out.splitlines():
|
||||||
|
start, size, num, name = line.split(maxsplit=3)
|
||||||
|
parts[int(num)] = Partition(int(start), int(size), name)
|
||||||
|
|
||||||
|
with open(fname, 'rb') as inf:
|
||||||
|
disk_data = inf.read()
|
||||||
|
|
||||||
|
test_abootimg.AbootimgTestDiskImage(cons, 'bootv4.img', test_abootimg.boot_img_hex)
|
||||||
|
boot_img = os.path.join(cons.config.result_dir, 'bootv4.img')
|
||||||
|
with open(boot_img, 'rb') as inf:
|
||||||
|
set_part_data(2, inf.read())
|
||||||
|
|
||||||
|
test_abootimg.AbootimgTestDiskImage(cons, 'vendor_boot.img', test_abootimg.vboot_img_hex)
|
||||||
|
vendor_boot_img = os.path.join(cons.config.result_dir, 'vendor_boot.img')
|
||||||
|
with open(vendor_boot_img, 'rb') as inf:
|
||||||
|
set_part_data(4, inf.read())
|
||||||
|
|
||||||
|
with open(fname, 'wb') as outf:
|
||||||
|
outf.write(disk_data)
|
||||||
|
|
||||||
|
print('wrote to {}'.format(fname))
|
||||||
|
|
||||||
|
return fname
|
||||||
|
|
||||||
def setup_cedit_file(cons):
|
def setup_cedit_file(cons):
|
||||||
infname = os.path.join(cons.config.source_dir,
|
infname = os.path.join(cons.config.source_dir,
|
||||||
|
@ -478,6 +556,7 @@ def test_ut_dm_init_bootstd(u_boot_console):
|
||||||
setup_bootmenu_image(u_boot_console)
|
setup_bootmenu_image(u_boot_console)
|
||||||
setup_cedit_file(u_boot_console)
|
setup_cedit_file(u_boot_console)
|
||||||
setup_cros_image(u_boot_console)
|
setup_cros_image(u_boot_console)
|
||||||
|
setup_android_image(u_boot_console)
|
||||||
|
|
||||||
# Restart so that the new mmc1.img is picked up
|
# Restart so that the new mmc1.img is picked up
|
||||||
u_boot_console.restart_uboot()
|
u_boot_console.restart_uboot()
|
||||||
|
|
Loading…
Add table
Reference in a new issue