From 7d850f85aad74ae907290ba6f911d362a0478e61 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 6 Jan 2023 08:52:19 -0600 Subject: sandbox: Enable mmc command and legacy images The mmc command is useful for testing mmc disk images in sandbox, so enable it. We also need to enable legacy images so that we can run tests which use them. Disable it for a few avb tests since MMC is not implemented there yet. Signed-off-by: Simon Glass --- test/py/tests/test_android/test_avb.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'test/py') diff --git a/test/py/tests/test_android/test_avb.py b/test/py/tests/test_android/test_avb.py index a3f883136b0..bc5c5b55821 100644 --- a/test/py/tests/test_android/test_avb.py +++ b/test/py/tests/test_android/test_avb.py @@ -39,6 +39,7 @@ def test_avb_verify(u_boot_console): @pytest.mark.buildconfigspec('cmd_avb') @pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.notbuildconfigspec('sandbox') def test_avb_mmc_uuid(u_boot_console): """Check if 'avb get_uuid' works, compare results with 'part list mmc 1' output @@ -97,6 +98,7 @@ def test_avb_is_unlocked(u_boot_console): @pytest.mark.buildconfigspec('cmd_avb') @pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.notbuildconfigspec('sandbox') def test_avb_mmc_read(u_boot_console): """Test mmc read operation """ -- cgit v1.2.3 From d985f1dbddb241c21a9150abf59dd386ba1ffe05 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 6 Jan 2023 08:52:41 -0600 Subject: bootstd: Add a test for the bootstd menu Add a test which checks that two operating systems can be displayed in a menu, allowing one to be selected. Enable a few things on snow so that the unit tests build. Signed-off-by: Simon Glass --- test/py/tests/bootstd/armbian.bmp.xz | Bin 0 -> 1384 bytes test/py/tests/bootstd/mmc4.img.xz | Bin 0 -> 7072 bytes test/py/tests/test_ut.py | 218 ++++++++++++++++++++++++++++++++--- 3 files changed, 199 insertions(+), 19 deletions(-) create mode 100644 test/py/tests/bootstd/armbian.bmp.xz create mode 100644 test/py/tests/bootstd/mmc4.img.xz (limited to 'test/py') diff --git a/test/py/tests/bootstd/armbian.bmp.xz b/test/py/tests/bootstd/armbian.bmp.xz new file mode 100644 index 00000000000..ad137ea6e6d Binary files /dev/null and b/test/py/tests/bootstd/armbian.bmp.xz differ diff --git a/test/py/tests/bootstd/mmc4.img.xz b/test/py/tests/bootstd/mmc4.img.xz new file mode 100644 index 00000000000..f4db011969f Binary files /dev/null and b/test/py/tests/bootstd/mmc4.img.xz differ diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index bab8b97672b..6958fabfa34 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. +import getpass import gzip import os import os.path @@ -13,34 +14,217 @@ def mkdir_cond(dirname): """Create a directory if it doesn't already exist Args: - dirname: Name of directory to create + dirname (str): Name of directory to create """ if not os.path.exists(dirname): os.mkdir(dirname) -def setup_bootflow_image(u_boot_console): - """Create a 20MB disk image with a single FAT partition""" - cons = u_boot_console - fname = os.path.join(cons.config.source_dir, 'mmc1.img') +def setup_image(cons, mmc_dev, part_type): + """Create a 20MB disk image with a single partition + + Args: + cons (ConsoleBase): Console to use + mmc_dev (int): MMC device number to use, e.g. 1 + part_type (int): Partition type, e.g. 0xc for FAT32 + + Returns: + tuple: + str: Filename of MMC image + str: Directory name of 'mnt' directory + """ + fname = os.path.join(cons.config.source_dir, f'mmc{mmc_dev}.img') mnt = os.path.join(cons.config.persistent_data_dir, 'mnt') mkdir_cond(mnt) u_boot_utils.run_and_log(cons, 'qemu-img create %s 20M' % fname) u_boot_utils.run_and_log(cons, 'sudo sfdisk %s' % fname, - stdin=b'type=c') + stdin=f'type={part_type:x}'.encode('utf-8')) + return fname, mnt + +def mount_image(cons, fname, mnt, fstype): + """Create a filesystem and mount it on partition 1 + + Args: + cons (ConsoleBase): Console to use + fname (str): Filename of MMC image + mnt (str): Directory name of 'mnt' directory + fstype (str): Filesystem type ('vfat' or 'ext4') + + Returns: + str: Name of loop device used + """ + out = u_boot_utils.run_and_log(cons, 'sudo losetup --show -f -P %s' % fname) + loop = out.strip() + part = f'{loop}p1' + u_boot_utils.run_and_log(cons, f'sudo mkfs.{fstype} {part}') + opts = '' + if fstype == 'vfat': + opts += ' -o uid={os.getuid()},gid={os.getgid()}' + u_boot_utils.run_and_log(cons, f'sudo mount -o loop {part} {mnt}{opts}') + u_boot_utils.run_and_log(cons, f'sudo chown {getpass.getuser()} {mnt}') + return loop + +def copy_prepared_image(cons, mmc_dev, fname): + """Use a prepared image since we cannot create one + + Args: + cons (ConsoleBase): Console touse + mmc_dev (int): MMC device number + fname (str): Filename of MMC image + """ + infname = os.path.join(cons.config.source_dir, + f'test/py/tests/bootstd/mmc{mmc_dev}.img.xz') + u_boot_utils.run_and_log( + cons, + ['sh', '-c', 'xz -dc %s >%s' % (infname, fname)]) + +def setup_bootmenu_image(cons): + """Create a 20MB disk image with a single ext4 partition + + This is modelled on Armbian 22.08 Jammy + """ + mmc_dev = 4 + fname, mnt = setup_image(cons, mmc_dev, 0x83) loop = None mounted = False complete = False try: - out = u_boot_utils.run_and_log(cons, - 'sudo losetup --show -f -P %s' % fname) - loop = out.strip() - fatpart = '%sp1' % loop - u_boot_utils.run_and_log(cons, 'sudo mkfs.vfat %s' % fatpart) + loop = mount_image(cons, fname, mnt, 'ext4') + mounted = True + + vmlinux = 'Image' + initrd = 'uInitrd' + dtbdir = 'dtb' + script = '''# DO NOT EDIT THIS FILE +# +# Please edit /boot/armbianEnv.txt to set supported parameters +# + +setenv load_addr "0x9000000" +setenv overlay_error "false" +# default values +setenv rootdev "/dev/mmcblk%dp1" +setenv verbosity "1" +setenv console "both" +setenv bootlogo "false" +setenv rootfstype "ext4" +setenv docker_optimizations "on" +setenv earlycon "off" + +echo "Boot script loaded from ${devtype} ${devnum}" + +if test -e ${devtype} ${devnum} ${prefix}armbianEnv.txt; then + load ${devtype} ${devnum} ${load_addr} ${prefix}armbianEnv.txt + env import -t ${load_addr} ${filesize} +fi + +if test "${logo}" = "disabled"; then setenv logo "logo.nologo"; fi + +if test "${console}" = "display" || test "${console}" = "both"; then setenv consoleargs "console=tty1"; fi +if test "${console}" = "serial" || test "${console}" = "both"; then setenv consoleargs "console=ttyS2,1500000 ${consoleargs}"; fi +if test "${earlycon}" = "on"; then setenv consoleargs "earlycon ${consoleargs}"; fi +if test "${bootlogo}" = "true"; then setenv consoleargs "bootsplash.bootfile=bootsplash.armbian ${consoleargs}"; fi + +# get PARTUUID of first partition on SD/eMMC the boot script was loaded from +if test "${devtype}" = "mmc"; then part uuid mmc ${devnum}:1 partuuid; fi + +setenv bootargs "root=${rootdev} rootwait rootfstype=${rootfstype} ${consoleargs} consoleblank=0 loglevel=${verbosity} ubootpart=${partuuid} usb-storage.quirks=${usbstoragequirks} ${extraargs} ${extraboardargs}" + +if test "${docker_optimizations}" = "on"; then setenv bootargs "${bootargs} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1"; fi + +load ${devtype} ${devnum} ${ramdisk_addr_r} ${prefix}uInitrd +load ${devtype} ${devnum} ${kernel_addr_r} ${prefix}Image + +load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile} +fdt addr ${fdt_addr_r} +fdt resize 65536 +for overlay_file in ${overlays}; do + if load ${devtype} ${devnum} ${load_addr} ${prefix}dtb/rockchip/overlay/${overlay_prefix}-${overlay_file}.dtbo; then + echo "Applying kernel provided DT overlay ${overlay_prefix}-${overlay_file}.dtbo" + fdt apply ${load_addr} || setenv overlay_error "true" + fi +done +for overlay_file in ${user_overlays}; do + if load ${devtype} ${devnum} ${load_addr} ${prefix}overlay-user/${overlay_file}.dtbo; then + echo "Applying user provided DT overlay ${overlay_file}.dtbo" + fdt apply ${load_addr} || setenv overlay_error "true" + fi +done +if test "${overlay_error}" = "true"; then + echo "Error applying DT overlays, restoring original DT" + load ${devtype} ${devnum} ${fdt_addr_r} ${prefix}dtb/${fdtfile} +else + if load ${devtype} ${devnum} ${load_addr} ${prefix}dtb/rockchip/overlay/${overlay_prefix}-fixup.scr; then + echo "Applying kernel provided DT fixup script (${overlay_prefix}-fixup.scr)" + source ${load_addr} + fi + if test -e ${devtype} ${devnum} ${prefix}fixup.scr; then + load ${devtype} ${devnum} ${load_addr} ${prefix}fixup.scr + echo "Applying user provided fixup script (fixup.scr)" + source ${load_addr} + fi +fi +booti ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r} + +# Recompile with: +# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr +''' % (mmc_dev) + bootdir = os.path.join(mnt, 'boot') + mkdir_cond(bootdir) + cmd_fname = os.path.join(bootdir, 'boot.cmd') + scr_fname = os.path.join(bootdir, 'boot.scr') + with open(cmd_fname, 'w') as outf: + print(script, file=outf) + + infname = os.path.join(cons.config.source_dir, + 'test/py/tests/bootstd/armbian.bmp.xz') + bmp_file = os.path.join(bootdir, 'boot.bmp') + u_boot_utils.run_and_log( + cons, + ['sh', '-c', f'xz -dc {infname} >{bmp_file}']) + + u_boot_utils.run_and_log( + cons, f'mkimage -C none -A arm -T script -d {cmd_fname} {scr_fname}') + + kernel = 'vmlinuz-5.15.63-rockchip64' + target = os.path.join(bootdir, kernel) + with open(target, 'wb') as outf: + print('kernel', outf) + + symlink = os.path.join(bootdir, 'Image') + if os.path.exists(symlink): + os.remove(symlink) + u_boot_utils.run_and_log( + cons, f'echo here {kernel} {symlink}') + os.symlink(kernel, symlink) + u_boot_utils.run_and_log( - cons, 'sudo mount -o loop %s %s -o uid=%d,gid=%d' % - (fatpart, mnt, os.getuid(), os.getgid())) + cons, f'mkimage -C none -A arm -T script -d {cmd_fname} {scr_fname}') + complete = True + + except ValueError as exc: + print('Falled to create image, failing back to prepared copy: %s', + str(exc)) + finally: + if mounted: + u_boot_utils.run_and_log(cons, 'sudo umount %s' % mnt) + if loop: + u_boot_utils.run_and_log(cons, 'sudo losetup -d %s' % loop) + + if not complete: + copy_prepared_image(cons, mmc_dev, fname) + +def setup_bootflow_image(cons): + """Create a 20MB disk image with a single FAT partition""" + mmc_dev = 1 + fname, mnt = setup_image(cons, mmc_dev, 0xc) + + loop = None + mounted = False + complete = False + try: + loop = mount_image(cons, fname, mnt, 'vfat') mounted = True vmlinux = 'vmlinuz-5.3.7-301.fc31.armv7hl' @@ -90,12 +274,7 @@ label Fedora-Workstation-armhfp-31-1.9 (5.3.7-301.fc31.armv7hl) u_boot_utils.run_and_log(cons, 'sudo losetup -d %s' % loop) if not complete: - # Use a prepared image since we cannot create one - infname = os.path.join(cons.config.source_dir, - 'test/py/tests/bootstd/mmc1.img.xz') - u_boot_utils.run_and_log( - cons, - ['sh', '-c', 'xz -dc %s >%s' % (infname, fname)]) + copy_prepared_image(cons, mmc_dev, fname) @pytest.mark.buildconfigspec('ut_dm') @@ -134,6 +313,7 @@ def test_ut_dm_init_bootstd(u_boot_console): """Initialise data for bootflow tests""" setup_bootflow_image(u_boot_console) + setup_bootmenu_image(u_boot_console) # Restart so that the new mmc1.img is picked up u_boot_console.restart_uboot() -- cgit v1.2.3