mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
test: boot: Add test for bootmeth_rauc
Add a simple unit test for testing the RAUC bootmethod. Provide only the very basic tests for now, running a scan and list, to verify correct detection of the RAUC bootmethod. More advanced boot tests of this bootmethod can be added in a separate patch. This requires another mmc image (mmc10) to contain the following partitions: 1. boot A: contains a dummy boot.scr 2. root A: contains an empty root filesystem 3. boot B: contains a dummy boot.scr 4. root B: contains an empty root filesystem The bootmeth_rauc scans all four partitions for existence and expects a boot script in each boot partition. Also add BOOTMETH_RAUC as a dependency on sandbox so that we can test this with: $ ./test/py/test.py -B sandbox --build -k test_ut # build the mmc10.img $ ./test/py/test.py -B sandbox --build -k bootflow_rauc Signed-off-by: Martin Schwan <m.schwan@phytec.de> Reviewed-by: Simon Glass <simon.glass@canonical.com> [trini: mmc9 is now in use, switch to mmc10] Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
@@ -46,6 +46,8 @@
|
|||||||
mmc6 = "/mmc6";
|
mmc6 = "/mmc6";
|
||||||
mmc7 = "/mmc7";
|
mmc7 = "/mmc7";
|
||||||
mmc8 = "/mmc8";
|
mmc8 = "/mmc8";
|
||||||
|
mmc9 = "/mmc9";
|
||||||
|
mmc10 = "/mmc10";
|
||||||
pci0 = &pci0;
|
pci0 = &pci0;
|
||||||
pci1 = &pci1;
|
pci1 = &pci1;
|
||||||
pci2 = &pci2;
|
pci2 = &pci2;
|
||||||
@@ -1279,6 +1281,13 @@
|
|||||||
filename = "mmc9.img";
|
filename = "mmc9.img";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This is used for RAUC boot tests */
|
||||||
|
mmc10 {
|
||||||
|
status = "disabled";
|
||||||
|
compatible = "sandbox,mmc";
|
||||||
|
filename = "mmc10.img";
|
||||||
|
};
|
||||||
|
|
||||||
pch {
|
pch {
|
||||||
compatible = "sandbox,pch";
|
compatible = "sandbox,pch";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ CONFIG_FIT=y
|
|||||||
CONFIG_FIT_CIPHER=y
|
CONFIG_FIT_CIPHER=y
|
||||||
CONFIG_FIT_VERBOSE=y
|
CONFIG_FIT_VERBOSE=y
|
||||||
CONFIG_BOOTMETH_ANDROID=y
|
CONFIG_BOOTMETH_ANDROID=y
|
||||||
|
CONFIG_BOOTMETH_RAUC=y
|
||||||
CONFIG_UPL=y
|
CONFIG_UPL=y
|
||||||
CONFIG_LEGACY_IMAGE_FORMAT=y
|
CONFIG_LEGACY_IMAGE_FORMAT=y
|
||||||
CONFIG_MEASURED_BOOT=y
|
CONFIG_MEASURED_BOOT=y
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
|
|
||||||
extern U_BOOT_DRIVER(bootmeth_android);
|
extern U_BOOT_DRIVER(bootmeth_android);
|
||||||
extern U_BOOT_DRIVER(bootmeth_cros);
|
extern U_BOOT_DRIVER(bootmeth_cros);
|
||||||
|
extern U_BOOT_DRIVER(bootmeth_rauc);
|
||||||
extern U_BOOT_DRIVER(bootmeth_2script);
|
extern U_BOOT_DRIVER(bootmeth_2script);
|
||||||
|
|
||||||
/* Use this as the vendor for EFI to tell the app to exit boot services */
|
/* Use this as the vendor for EFI to tell the app to exit boot services */
|
||||||
@@ -1392,6 +1393,62 @@ static int bootflow_efi(struct unit_test_state *uts)
|
|||||||
}
|
}
|
||||||
BOOTSTD_TEST(bootflow_efi, UTF_CONSOLE);
|
BOOTSTD_TEST(bootflow_efi, UTF_CONSOLE);
|
||||||
|
|
||||||
|
/* Test RAUC bootmeth */
|
||||||
|
static int bootflow_rauc(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
const char *mmc_dev = "mmc10";
|
||||||
|
struct bootstd_priv *std;
|
||||||
|
struct udevice *bootstd;
|
||||||
|
static const char *order[] = {NULL, NULL};
|
||||||
|
const char **old_order;
|
||||||
|
ofnode root;
|
||||||
|
ofnode node;
|
||||||
|
|
||||||
|
order[0] = mmc_dev;
|
||||||
|
|
||||||
|
if (!CONFIG_IS_ENABLED(BOOTMETH_RAUC))
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
/* Enable the requested mmc node since we need a different bootflow */
|
||||||
|
root = oftree_root(oftree_default());
|
||||||
|
node = ofnode_find_subnode(root, mmc_dev);
|
||||||
|
ut_assert(ofnode_valid(node));
|
||||||
|
ut_assertok(lists_bind_fdt(gd->dm_root, node, NULL, NULL, false));
|
||||||
|
|
||||||
|
/* Enable the rauc bootmeth */
|
||||||
|
ut_assertok(uclass_first_device_err(UCLASS_BOOTSTD, &bootstd));
|
||||||
|
ut_assertok(device_bind(bootstd, DM_DRIVER_REF(bootmeth_rauc),
|
||||||
|
"rauc", 0, ofnode_null(), NULL));
|
||||||
|
|
||||||
|
/* Change the device and bootmeth order */
|
||||||
|
std = dev_get_priv(bootstd);
|
||||||
|
old_order = std->bootdev_order;
|
||||||
|
std->bootdev_order = order;
|
||||||
|
|
||||||
|
ut_assertok(bootmeth_set_order("rauc"));
|
||||||
|
|
||||||
|
/* Run scan and list */
|
||||||
|
ut_assertok(run_command("bootflow scan", 0));
|
||||||
|
ut_assert_console_end();
|
||||||
|
|
||||||
|
ut_assertok(run_command("bootflow list", 0));
|
||||||
|
|
||||||
|
ut_assert_nextlinen("Showing all");
|
||||||
|
ut_assert_nextlinen("Seq");
|
||||||
|
ut_assert_nextlinen("---");
|
||||||
|
ut_assert_nextlinen(" 0 rauc ready mmc 0 mmc10.bootdev.whole ");
|
||||||
|
ut_assert_nextlinen("---");
|
||||||
|
ut_assert_skip_to_line("(1 bootflow, 1 valid)");
|
||||||
|
|
||||||
|
ut_assert_console_end();
|
||||||
|
|
||||||
|
/* Restore the order used by the device tree */
|
||||||
|
std->bootdev_order = old_order;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
BOOTSTD_TEST(bootflow_rauc, UTF_CONSOLE | UTF_DM | UTF_SCAN_FDT);
|
||||||
|
|
||||||
/* Check 'bootflow scan' provides a list of images */
|
/* Check 'bootflow scan' provides a list of images */
|
||||||
static int bootstd_images(struct unit_test_state *uts)
|
static int bootstd_images(struct unit_test_state *uts)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -554,6 +554,52 @@ def setup_efi_image(ubman):
|
|||||||
utils.run_and_log(ubman, f'rm -rf {mnt}')
|
utils.run_and_log(ubman, f'rm -rf {mnt}')
|
||||||
utils.run_and_log(ubman, f'rm -f {fsfile}')
|
utils.run_and_log(ubman, f'rm -f {fsfile}')
|
||||||
|
|
||||||
|
def setup_rauc_image(ubman):
|
||||||
|
"""Create a 40MB disk image with an A/B RAUC system on it"""
|
||||||
|
mmc_dev = 10
|
||||||
|
fname = os.path.join(ubman.config.source_dir, f'mmc{mmc_dev}.img')
|
||||||
|
mnt = ubman.config.persistent_data_dir
|
||||||
|
|
||||||
|
spec = 'type=c, size=8M, start=1M, bootable\n' \
|
||||||
|
'type=83, size=10M\n' \
|
||||||
|
'type=c, size=8M, bootable\n' \
|
||||||
|
'type=83, size=10M'
|
||||||
|
|
||||||
|
utils.run_and_log(ubman, f'qemu-img create {fname} 40M')
|
||||||
|
utils.run_and_log(ubman, ['sh', '-c', f'printf "{spec}" | sfdisk {fname}'])
|
||||||
|
|
||||||
|
# Generate boot script
|
||||||
|
script = '# dummy boot script'
|
||||||
|
bootdir = os.path.join(mnt, 'boot')
|
||||||
|
utils.run_and_log(ubman, f'mkdir -p {bootdir}')
|
||||||
|
cmd_fname = os.path.join(bootdir, 'boot.cmd')
|
||||||
|
scr_fname = os.path.join(bootdir, 'boot.scr')
|
||||||
|
with open(cmd_fname, 'w', encoding='ascii') as outf:
|
||||||
|
print(script, file=outf)
|
||||||
|
|
||||||
|
mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage')
|
||||||
|
utils.run_and_log(
|
||||||
|
ubman, f'{mkimage} -C none -A arm -T script -d {cmd_fname} {scr_fname}')
|
||||||
|
utils.run_and_log(ubman, f'rm -f {cmd_fname}')
|
||||||
|
|
||||||
|
# Generate empty rootfs
|
||||||
|
rootdir = os.path.join(mnt, 'root')
|
||||||
|
utils.run_and_log(ubman, f'mkdir -p {rootdir}')
|
||||||
|
|
||||||
|
# Create boot filesystem image with boot script in it and copy to disk image
|
||||||
|
fsfile = f'rauc_boot.fat32.img'
|
||||||
|
fs_helper.mk_fs(ubman.config, 'fat32', 0x800000, fsfile.split('.')[0], bootdir)
|
||||||
|
utils.run_and_log(ubman, f'dd if={mnt}/{fsfile} of=mmc{mmc_dev}.img bs=1M seek=1 conv=notrunc')
|
||||||
|
utils.run_and_log(ubman, f'dd if={mnt}/{fsfile} of=mmc{mmc_dev}.img bs=1M seek=19 conv=notrunc')
|
||||||
|
utils.run_and_log(ubman, f'rm -f {scr_fname}')
|
||||||
|
|
||||||
|
# Create empty root filesystem image and copy to disk image
|
||||||
|
fsfile = f'rauc_root.ext4.img'
|
||||||
|
fs_helper.mk_fs(ubman.config, 'ext4', 0xa00000, fsfile.split('.')[0], rootdir)
|
||||||
|
utils.run_and_log(ubman, f'dd if={mnt}/{fsfile} of=mmc{mmc_dev}.img bs=1M seek=9 conv=notrunc')
|
||||||
|
utils.run_and_log(ubman, f'dd if={mnt}/{fsfile} of=mmc{mmc_dev}.img bs=1M seek=27 conv=notrunc')
|
||||||
|
utils.run_and_log(ubman, f'rm -f {fsfile}')
|
||||||
|
|
||||||
@pytest.mark.buildconfigspec('cmd_bootflow')
|
@pytest.mark.buildconfigspec('cmd_bootflow')
|
||||||
@pytest.mark.buildconfigspec('sandbox')
|
@pytest.mark.buildconfigspec('sandbox')
|
||||||
def test_ut_dm_init_bootstd(ubman):
|
def test_ut_dm_init_bootstd(ubman):
|
||||||
@@ -565,6 +611,7 @@ def test_ut_dm_init_bootstd(ubman):
|
|||||||
setup_cros_image(ubman)
|
setup_cros_image(ubman)
|
||||||
setup_android_image(ubman)
|
setup_android_image(ubman)
|
||||||
setup_efi_image(ubman)
|
setup_efi_image(ubman)
|
||||||
|
setup_rauc_image(ubman)
|
||||||
|
|
||||||
# Restart so that the new mmc1.img is picked up
|
# Restart so that the new mmc1.img is picked up
|
||||||
ubman.restart_uboot()
|
ubman.restart_uboot()
|
||||||
|
|||||||
Reference in New Issue
Block a user