aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2023-08-24 13:55:45 -0600
committerTom Rini <trini@konsulko.com>2023-08-26 10:07:32 -0400
commit71f634b822ae6613c43fc960d5afbe5b5d728fb4 (patch)
tree4f1d3e80cbca579f5dc8ba678391e1cb499a80a4
parent966b16c59a70cd2e3383eb77d49c1e62b093b36f (diff)
downloadu-boot-71f634b822ae6613c43fc960d5afbe5b5d728fb4.zip
u-boot-71f634b822ae6613c43fc960d5afbe5b5d728fb4.tar.gz
u-boot-71f634b822ae6613c43fc960d5afbe5b5d728fb4.tar.bz2
bootstd: cros: Allow detection of any kernel partition
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 <sjg@chromium.org> Suggested-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> [trini: Add missing select of PARTITION_TYPE_GUID] Signed-off-by: Tom Rini <trini@konsulko.com>
-rw-r--r--boot/Kconfig3
-rw-r--r--boot/bootmeth_cros.c48
-rw-r--r--test/boot/bootflow.c5
3 files changed, 36 insertions, 20 deletions
diff --git a/boot/Kconfig b/boot/Kconfig
index 5e2d428..86ccfd7 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -466,6 +466,9 @@ config BOOTMETH_CROS
bool "Bootdev support for Chromium OS"
depends on X86 || ARM || SANDBOX
default y if !ARM
+ select EFI_PARTITION
+ 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 1776fb1..20e0b1e 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 ae34370..1ff2320 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();