All of lore.kernel.org
 help / color / mirror / Atom feed
From: Julien Masson <jmasson@baylibre.com>
To: Mattijs Korpershoek <mkorpershoek@baylibre.com>,
	Simon Glass <sjg@chromium.org>
Cc: Julien Masson <jmasson@baylibre.com>,
	Guillaume La Roque <glaroque@baylibre.com>,
	Dmitrii Merkurev <dimorinny@google.com>,
	Roman Stratiienko <r.stratiienko@gmail.com>,
	Igor Opaniuk <igor.opaniuk@gmail.com>, <u-boot@lists.denx.de>,
	Mattijs Korpershoek <mkorpershoek@baylibre.com>
Subject: Re: [PATCH v2 5/5] bootstd: Add test for bootmeth_android
Date: Thu, 13 Jun 2024 16:19:58 +0200	[thread overview]
Message-ID: <87ed90ncvl.fsf@baylibre.com> (raw)
In-Reply-To: <20240613-bootmeth-android-v2-5-397f6e66eb29@baylibre.com>


On Thu 13 Jun 2024 at 16:19, Mattijs Korpershoek <mkorpershoek@baylibre.com> wrote:

> 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_abootimg # build bootv4.img
> $ ./test/py/test.py --bd sandbox --build -k test_ut # build the mmc7.img
> $ ./test/py/test.py --bd sandbox --build -k bootflow_android
> 
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
> ---
>  arch/sandbox/dts/test.dts |  8 +++++
>  configs/sandbox_defconfig |  2 +-
>  test/boot/bootflow.c      | 65 ++++++++++++++++++++++++++++++++++++++--
>  test/py/tests/test_ut.py  | 76 +++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 147 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> index a012f5c4c9ba..5fb5eac862ec 100644
> --- a/arch/sandbox/dts/test.dts
> +++ b/arch/sandbox/dts/test.dts
> @@ -43,6 +43,7 @@
>  		mmc4 = "/mmc4";
>  		mmc5 = "/mmc5";
>  		mmc6 = "/mmc6";
> +		mmc7 = "/mmc7";
>  		pci0 = &pci0;
>  		pci1 = &pci1;
>  		pci2 = &pci2;
> @@ -1129,6 +1130,13 @@
>  		filename = "mmc6.img";
>  	};
>  
> +	/* This is used for Android tests */
> +	mmc7 {
> +		status = "disabled";
> +		compatible = "sandbox,mmc";
> +		filename = "mmc7.img";
> +	};
> +
>  	pch {
>  		compatible = "sandbox,pch";
>  	};
> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
> index 93b52f2de5cf..bc4398f101a7 100644
> --- a/configs/sandbox_defconfig
> +++ b/configs/sandbox_defconfig
> @@ -15,6 +15,7 @@ CONFIG_FIT=y
>  CONFIG_FIT_RSASSA_PSS=y
>  CONFIG_FIT_CIPHER=y
>  CONFIG_FIT_VERBOSE=y
> +CONFIG_BOOTMETH_ANDROID=y
>  CONFIG_LEGACY_IMAGE_FORMAT=y
>  CONFIG_MEASURED_BOOT=y
>  CONFIG_BOOTSTAGE=y
> @@ -40,7 +41,6 @@ CONFIG_LOG_MAX_LEVEL=9
>  CONFIG_LOG_DEFAULT_LEVEL=6
>  CONFIG_DISPLAY_BOARDINFO_LATE=y
>  CONFIG_STACKPROTECTOR=y
> -CONFIG_ANDROID_AB=y
>  CONFIG_CMD_CPU=y
>  CONFIG_CMD_LICENSE=y
>  CONFIG_CMD_SMBIOS=y
> diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
> index 4511cfa7f9bf..934c4dcbad2b 100644
> --- a/test/boot/bootflow.c
> +++ b/test/boot/bootflow.c
> @@ -27,6 +27,7 @@
>  
>  DECLARE_GLOBAL_DATA_PTR;
>  
> +extern U_BOOT_DRIVER(bootmeth_android);
>  extern U_BOOT_DRIVER(bootmeth_cros);
>  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
>   * @mmc_dev: MMC device to use, e.g. "mmc4". Note that this must remain valid
>   *	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
>   * Returns 0 on success, -ve on failure
>   */
>  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};
>  	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));
>  
>  	/* 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(device_bind(bootstd, DM_DRIVER_REF(bootmeth_cros),
>  					"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 */
>  	std = dev_get_priv(bootstd);
>  	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;
>  }
>  
> +/**
> + * 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
>   *
> @@ -1160,3 +1199,23 @@ static int bootflow_cros(struct unit_test_state *uts)
>  	return 0;
>  }
>  BOOTSTD_TEST(bootflow_cros, 0);
> +
> +/* Test Android bootmeth  */
> +static int bootflow_android(struct unit_test_state *uts)
> +{
> +	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);
> diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
> index c169c835e38a..39e1abe02a68 100644
> --- a/test/py/tests/test_ut.py
> +++ b/test/py/tests/test_ut.py
> @@ -423,6 +423,81 @@ def setup_cros_image(cons):
>  
>      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()
> +
> +    boot_img = os.path.join(cons.config.result_dir, 'bootv4.img')
> +    with open(boot_img, 'rb') as inf:
> +        set_part_data(2, inf.read())
> +
> +    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):
>      infname = os.path.join(cons.config.source_dir,
> @@ -477,6 +552,7 @@ def test_ut_dm_init_bootstd(u_boot_console):
>      setup_bootmenu_image(u_boot_console)
>      setup_cedit_file(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
>      u_boot_console.restart_uboot()
> 
> -- 
> 2.45.2
> 

Reviewed-by: Julien Masson <jmasson@baylibre.com>
-- 
Julien Masson

  reply	other threads:[~2024-06-13 14:20 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-13 10:13 [PATCH v2 0/5] bootstd: Add Android support Mattijs Korpershoek
2024-06-13 10:13 ` [PATCH v2 1/5] boot: android: Provide vendor_bootimg_addr in boot_get_fdt() Mattijs Korpershoek
2024-06-13 15:22   ` Simon Glass
2024-06-13 15:42   ` Julien Masson
2024-06-13 17:10   ` Igor Opaniuk
2024-06-13 18:43   ` Guillaume LA ROQUE
2024-06-13 10:13 ` [PATCH v2 2/5] bootstd: Add bootflow_iter_check_mmc() helper Mattijs Korpershoek
2024-06-13 14:16   ` Julien Masson
2024-06-13 18:44   ` Guillaume LA ROQUE
2024-06-13 10:13 ` [PATCH v2 3/5] android: boot: Add set_abootimg_addr() and set_avendor_bootimg_addr() Mattijs Korpershoek
2024-06-13 14:16   ` Julien Masson
2024-06-13 15:20   ` Simon Glass
2024-06-13 18:45   ` Guillaume LA ROQUE
2024-06-13 10:13 ` [PATCH v2 4/5] bootstd: Add a bootmeth for Android Mattijs Korpershoek
2024-06-13 14:19   ` Julien Masson
2024-06-13 10:13 ` [PATCH v2 5/5] bootstd: Add test for bootmeth_android Mattijs Korpershoek
2024-06-13 14:19   ` Julien Masson [this message]
2024-06-13 18:47   ` Guillaume LA ROQUE
2024-06-14  9:53 ` [PATCH v2 0/5] bootstd: Add Android support Guillaume LA ROQUE
2024-06-14 11:44   ` Mattijs Korpershoek
2024-06-17 13:53 ` Simon Glass
2024-06-17 15:15   ` Mattijs Korpershoek
2024-06-19  3:03     ` Simon Glass
2024-06-19  9:25       ` Mattijs Korpershoek
2024-07-24 12:43       ` Mattijs Korpershoek
2024-06-20 14:23 ` Tom Rini
2024-07-04  9:09   ` Mattijs Korpershoek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ed90ncvl.fsf@baylibre.com \
    --to=jmasson@baylibre.com \
    --cc=dimorinny@google.com \
    --cc=glaroque@baylibre.com \
    --cc=igor.opaniuk@gmail.com \
    --cc=mkorpershoek@baylibre.com \
    --cc=r.stratiienko@gmail.com \
    --cc=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.