The existing ChromiumOS bootmeth only supports reading a single kernel
partition, either 2 or 4. In fact there are normally two options
available.

Use the GUID to detect kernel partitions, with the BOOTMETHF_ANY_PART
flag, so that bootstd does not require a valid filesystem before calling
the bootmeth.

Tidy up and improve the logging while we are here.

Signed-off-by: Simon Glass <s...@chromium.org>
Suggested-by: Alper Nebi Yasak <alpernebiya...@gmail.com>
---

Changes in v2:
- Rebase to -next

 boot/Kconfig         |  2 ++
 boot/bootmeth_cros.c | 48 +++++++++++++++++++++++++++-----------------
 test/boot/bootflow.c |  5 +++--
 3 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/boot/Kconfig b/boot/Kconfig
index 5e2d4286aeaa..b385902b53fe 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -466,6 +466,8 @@ config BOOTMETH_CROS
        bool "Bootdev support for Chromium OS"
        depends on X86 || ARM || SANDBOX
        default y if !ARM
+       select PARTITION_TYPE_GUID
+       select PARTITION_UUIDS
        help
          Enables support for booting Chromium OS using bootdevs. This uses the
          kernel A slot and obtains the kernel command line from the parameters
diff --git a/boot/bootmeth_cros.c b/boot/bootmeth_cros.c
index 1776fb1838c6..20e0b1e89c36 100644
--- a/boot/bootmeth_cros.c
+++ b/boot/bootmeth_cros.c
@@ -16,16 +16,19 @@
 #include <bootmeth.h>
 #include <display_options.h>
 #include <dm.h>
+#include <efi.h>
 #include <malloc.h>
 #include <mapmem.h>
 #include <part.h>
 #include <linux/sizes.h>
 #include "bootmeth_cros.h"
 
+static const efi_guid_t cros_kern_type = PARTITION_CROS_KERNEL;
+
 /*
  * Layout of the ChromeOS kernel
  *
- * Partitions 2 and 4 contain kernels
+ * Partitions 2 and 4 contain kernels with type GUID_CROS_KERNEL
  *
  * Contents are:
  *
@@ -145,13 +148,25 @@ static int scan_part(struct udevice *blk, int partnum,
 {
        struct blk_desc *desc = dev_get_uclass_plat(blk);
        struct vb2_keyblock *hdr;
+       struct uuid type;
        ulong num_blks;
        int ret;
 
+       if (!partnum)
+               return log_msg_ret("efi", -ENOENT);
+
        ret = part_get_info(desc, partnum, info);
        if (ret)
                return log_msg_ret("part", ret);
 
+       /* Check for kernel partition type */
+       log_debug("part %x: type=%s\n", partnum, info->type_guid);
+       if (uuid_str_to_bin(info->type_guid, (u8 *)&type, UUID_STR_FORMAT_GUID))
+               return log_msg_ret("typ", -EINVAL);
+
+       if (memcmp(&cros_kern_type, &type, sizeof(type)))
+               return log_msg_ret("typ", -ENOEXEC);
+
        /* Make a buffer for the header information */
        num_blks = PROBE_SIZE >> desc->log2blksz;
        log_debug("Reading header, blk=%s, start=%lx, blocks=%lx\n",
@@ -167,6 +182,7 @@ static int scan_part(struct udevice *blk, int partnum,
 
        if (memcmp(VB2_KEYBLOCK_MAGIC, hdr->magic, VB2_KEYBLOCK_MAGIC_SIZE)) {
                free(hdr);
+               log_debug("no magic\n");
                return -ENOENT;
        }
 
@@ -340,24 +356,16 @@ static int cros_read_bootflow(struct udevice *dev, struct 
bootflow *bflow)
        struct vb2_keyblock *hdr;
        const char *uuid = NULL;
        struct cros_priv *priv;
-       int part, ret;
-
-       log_debug("starting, part=%d\n", bflow->part);
+       int ret;
 
-       /* We consider the whole disk, not any one partition */
-       if (bflow->part)
-               return log_msg_ret("max", -ENOENT);
+       log_debug("starting, part=%x\n", bflow->part);
 
-       /* Check partition 2 then 4 */
-       part = 2;
-       ret = scan_part(bflow->blk, part, &info, &hdr);
+       /* Check for kernel partitions */
+       ret = scan_part(bflow->blk, bflow->part, &info, &hdr);
        if (ret) {
-               part = 4;
-               ret = scan_part(bflow->blk, part, &info, &hdr);
-               if (ret)
-                       return log_msg_ret("scan", ret);
+               log_debug("- scan failed: err=%d\n", ret);
+               return log_msg_ret("scan", ret);
        }
-       bflow->part = part;
 
        priv = malloc(sizeof(struct cros_priv));
        if (!priv) {
@@ -366,8 +374,8 @@ static int cros_read_bootflow(struct udevice *dev, struct 
bootflow *bflow)
        }
        bflow->bootmeth_priv = priv;
 
-       log_info("Selected partition %d, header at %lx\n", bflow->part,
-                (ulong)map_to_sysmem(hdr));
+       log_debug("Selected partition %d, header at %lx\n", bflow->part,
+                 (ulong)map_to_sysmem(hdr));
 
        /* Grab a few things from the preamble */
        preamble = (void *)hdr + hdr->keyblock_size;
@@ -381,8 +389,11 @@ static int cros_read_bootflow(struct udevice *dev, struct 
bootflow *bflow)
        ret = cros_read_info(bflow, uuid, preamble);
        preamble = NULL;
        free(hdr);
-       if (ret)
+       if (ret) {
+               free(priv->info_buf);
+               free(priv);
                return log_msg_ret("inf", ret);
+       }
        bflow->size = priv->body_size;
        bflow->state = BOOTFLOWST_READY;
 
@@ -437,6 +448,7 @@ static int cros_bootmeth_bind(struct udevice *dev)
        struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
 
        plat->desc = "ChromiumOS boot";
+       plat->flags = BOOTMETHF_ANY_PART;
 
        return 0;
 }
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index ae34370981cb..1ff2320c0365 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -983,9 +983,10 @@ static int bootflow_cros(struct unit_test_state *uts)
        ut_assert_nextlinen("Seq");
        ut_assert_nextlinen("---");
        ut_assert_nextlinen("  0  extlinux");
-       ut_assert_nextlinen("  1  cros         ready   mmc          2  
mmc5.bootdev.whole       ");
+       ut_assert_nextlinen("  1  cros         ready   mmc          2  
mmc5.bootdev.part_2       ");
+       ut_assert_nextlinen("  2  cros         ready   mmc          4  
mmc5.bootdev.part_4       ");
        ut_assert_nextlinen("---");
-       ut_assert_skip_to_line("(2 bootflows, 2 valid)");
+       ut_assert_skip_to_line("(3 bootflows, 3 valid)");
 
        ut_assert_console_end();
 
-- 
2.42.0.rc1.204.g551eb34607-goog

Reply via email to