diff options
author | Simon Glass <sjg@chromium.org> | 2023-08-24 13:55:45 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-08-26 10:07:32 -0400 |
commit | 71f634b822ae6613c43fc960d5afbe5b5d728fb4 (patch) | |
tree | 4f1d3e80cbca579f5dc8ba678391e1cb499a80a4 | |
parent | 966b16c59a70cd2e3383eb77d49c1e62b093b36f (diff) | |
download | u-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/Kconfig | 3 | ||||
-rw-r--r-- | boot/bootmeth_cros.c | 48 | ||||
-rw-r--r-- | test/boot/bootflow.c | 5 |
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(); |