mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-25 23:06:15 +00:00
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>
This commit is contained in:
parent
966b16c59a
commit
71f634b822
3 changed files with 36 additions and 20 deletions
|
@ -466,6 +466,9 @@ config BOOTMETH_CROS
|
||||||
bool "Bootdev support for Chromium OS"
|
bool "Bootdev support for Chromium OS"
|
||||||
depends on X86 || ARM || SANDBOX
|
depends on X86 || ARM || SANDBOX
|
||||||
default y if !ARM
|
default y if !ARM
|
||||||
|
select EFI_PARTITION
|
||||||
|
select PARTITION_TYPE_GUID
|
||||||
|
select PARTITION_UUIDS
|
||||||
help
|
help
|
||||||
Enables support for booting Chromium OS using bootdevs. This uses the
|
Enables support for booting Chromium OS using bootdevs. This uses the
|
||||||
kernel A slot and obtains the kernel command line from the parameters
|
kernel A slot and obtains the kernel command line from the parameters
|
||||||
|
|
|
@ -16,16 +16,19 @@
|
||||||
#include <bootmeth.h>
|
#include <bootmeth.h>
|
||||||
#include <display_options.h>
|
#include <display_options.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <efi.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <mapmem.h>
|
#include <mapmem.h>
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
#include "bootmeth_cros.h"
|
#include "bootmeth_cros.h"
|
||||||
|
|
||||||
|
static const efi_guid_t cros_kern_type = PARTITION_CROS_KERNEL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Layout of the ChromeOS 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:
|
* 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 blk_desc *desc = dev_get_uclass_plat(blk);
|
||||||
struct vb2_keyblock *hdr;
|
struct vb2_keyblock *hdr;
|
||||||
|
struct uuid type;
|
||||||
ulong num_blks;
|
ulong num_blks;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (!partnum)
|
||||||
|
return log_msg_ret("efi", -ENOENT);
|
||||||
|
|
||||||
ret = part_get_info(desc, partnum, info);
|
ret = part_get_info(desc, partnum, info);
|
||||||
if (ret)
|
if (ret)
|
||||||
return log_msg_ret("part", 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 */
|
/* Make a buffer for the header information */
|
||||||
num_blks = PROBE_SIZE >> desc->log2blksz;
|
num_blks = PROBE_SIZE >> desc->log2blksz;
|
||||||
log_debug("Reading header, blk=%s, start=%lx, blocks=%lx\n",
|
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)) {
|
if (memcmp(VB2_KEYBLOCK_MAGIC, hdr->magic, VB2_KEYBLOCK_MAGIC_SIZE)) {
|
||||||
free(hdr);
|
free(hdr);
|
||||||
|
log_debug("no magic\n");
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,24 +356,16 @@ static int cros_read_bootflow(struct udevice *dev, struct bootflow *bflow)
|
||||||
struct vb2_keyblock *hdr;
|
struct vb2_keyblock *hdr;
|
||||||
const char *uuid = NULL;
|
const char *uuid = NULL;
|
||||||
struct cros_priv *priv;
|
struct cros_priv *priv;
|
||||||
int part, ret;
|
int ret;
|
||||||
|
|
||||||
log_debug("starting, part=%d\n", bflow->part);
|
log_debug("starting, part=%x\n", bflow->part);
|
||||||
|
|
||||||
/* We consider the whole disk, not any one partition */
|
/* Check for kernel partitions */
|
||||||
if (bflow->part)
|
ret = scan_part(bflow->blk, bflow->part, &info, &hdr);
|
||||||
return log_msg_ret("max", -ENOENT);
|
|
||||||
|
|
||||||
/* Check partition 2 then 4 */
|
|
||||||
part = 2;
|
|
||||||
ret = scan_part(bflow->blk, part, &info, &hdr);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
part = 4;
|
log_debug("- scan failed: err=%d\n", ret);
|
||||||
ret = scan_part(bflow->blk, part, &info, &hdr);
|
return log_msg_ret("scan", ret);
|
||||||
if (ret)
|
|
||||||
return log_msg_ret("scan", ret);
|
|
||||||
}
|
}
|
||||||
bflow->part = part;
|
|
||||||
|
|
||||||
priv = malloc(sizeof(struct cros_priv));
|
priv = malloc(sizeof(struct cros_priv));
|
||||||
if (!priv) {
|
if (!priv) {
|
||||||
|
@ -366,8 +374,8 @@ static int cros_read_bootflow(struct udevice *dev, struct bootflow *bflow)
|
||||||
}
|
}
|
||||||
bflow->bootmeth_priv = priv;
|
bflow->bootmeth_priv = priv;
|
||||||
|
|
||||||
log_info("Selected partition %d, header at %lx\n", bflow->part,
|
log_debug("Selected partition %d, header at %lx\n", bflow->part,
|
||||||
(ulong)map_to_sysmem(hdr));
|
(ulong)map_to_sysmem(hdr));
|
||||||
|
|
||||||
/* Grab a few things from the preamble */
|
/* Grab a few things from the preamble */
|
||||||
preamble = (void *)hdr + hdr->keyblock_size;
|
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);
|
ret = cros_read_info(bflow, uuid, preamble);
|
||||||
preamble = NULL;
|
preamble = NULL;
|
||||||
free(hdr);
|
free(hdr);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
free(priv->info_buf);
|
||||||
|
free(priv);
|
||||||
return log_msg_ret("inf", ret);
|
return log_msg_ret("inf", ret);
|
||||||
|
}
|
||||||
bflow->size = priv->body_size;
|
bflow->size = priv->body_size;
|
||||||
bflow->state = BOOTFLOWST_READY;
|
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);
|
struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
|
||||||
|
|
||||||
plat->desc = "ChromiumOS boot";
|
plat->desc = "ChromiumOS boot";
|
||||||
|
plat->flags = BOOTMETHF_ANY_PART;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -983,9 +983,10 @@ static int bootflow_cros(struct unit_test_state *uts)
|
||||||
ut_assert_nextlinen("Seq");
|
ut_assert_nextlinen("Seq");
|
||||||
ut_assert_nextlinen("---");
|
ut_assert_nextlinen("---");
|
||||||
ut_assert_nextlinen(" 0 extlinux");
|
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_nextlinen("---");
|
||||||
ut_assert_skip_to_line("(2 bootflows, 2 valid)");
|
ut_assert_skip_to_line("(3 bootflows, 3 valid)");
|
||||||
|
|
||||||
ut_assert_console_end();
|
ut_assert_console_end();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue