summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/bootefi.c12
-rw-r--r--cmd/efidebug.c78
-rw-r--r--doc/develop/uefi/uefi.rst34
-rw-r--r--drivers/block/Makefile3
-rw-r--r--drivers/block/blkmap.c15
-rw-r--r--drivers/block/blkmap_helper.c53
-rw-r--r--include/blkmap.h29
-rw-r--r--include/efi_api.h5
-rw-r--r--include/efi_loader.h4
-rw-r--r--include/net.h17
-rw-r--r--lib/efi_loader/Kconfig9
-rw-r--r--lib/efi_loader/efi_bootmgr.c386
-rw-r--r--lib/efi_loader/efi_boottime.c7
-rw-r--r--lib/efi_loader/efi_disk.c18
-rw-r--r--lib/efi_loader/efi_setup.c7
-rw-r--r--net/wget.c205
-rw-r--r--test/py/tests/test_efi_secboot/test_signed.py42
-rw-r--r--test/py/tests/test_efi_secboot/test_signed_intca.py14
-rw-r--r--test/py/tests/test_efi_secboot/test_unsigned.py14
-rw-r--r--test/py/tests/test_fs/test_erofs.py9
-rw-r--r--test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py9
21 files changed, 908 insertions, 62 deletions
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 20e5c94a33..4d74969ad6 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -356,6 +356,7 @@ static efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options)
efi_status_t ret;
efi_uintn_t exit_data_size = 0;
u16 *exit_data = NULL;
+ struct efi_event *evt;
/* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
switch_to_non_secure_mode();
@@ -394,6 +395,17 @@ out:
log_err("Failed to remove loadfile2 for initrd\n");
}
+ /* Notify EFI_EVENT_GROUP_RETURN_TO_EFIBOOTMGR event group. */
+ list_for_each_entry(evt, &efi_events, link) {
+ if (evt->group &&
+ !guidcmp(evt->group,
+ &efi_guid_event_group_return_to_efibootmgr)) {
+ efi_signal_event(evt);
+ EFI_CALL(systab.boottime->close_event(evt));
+ break;
+ }
+ }
+
/* Control is returned to U-Boot, disable EFI watchdog */
efi_set_watchdog(0);
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 201531ac19..78ef16f4cb 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -19,6 +19,7 @@
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
+#include <net.h>
#include <part.h>
#include <search.h>
#include <linux/ctype.h>
@@ -708,6 +709,65 @@ out:
}
/**
+ * efi_boot_add_uri() - set URI load option
+ *
+ * @argc: Number of arguments
+ * @argv: Argument array
+ * @var_name16: variable name buffer
+ * @var_name16_size: variable name buffer size
+ * @lo: pointer to the load option
+ * @file_path: buffer to set the generated device path pointer
+ * @fp_size: file_path size
+ * Return: CMD_RET_SUCCESS on success,
+ * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
+ */
+static int efi_boot_add_uri(int argc, char *const argv[], u16 *var_name16,
+ size_t var_name16_size, struct efi_load_option *lo,
+ struct efi_device_path **file_path,
+ efi_uintn_t *fp_size)
+{
+ int id;
+ char *pos;
+ char *endp;
+ u16 *label;
+ efi_uintn_t uridp_len;
+ struct efi_device_path_uri *uridp;
+
+ if (argc < 3 || lo->label)
+ return CMD_RET_USAGE;
+
+ id = (int)hextoul(argv[1], &endp);
+ if (*endp != '\0' || id > 0xffff)
+ return CMD_RET_USAGE;
+
+ label = efi_convert_string(argv[2]);
+ if (!label)
+ return CMD_RET_FAILURE;
+
+ if (!wget_validate_uri(argv[3])) {
+ printf("ERROR: invalid URI\n");
+ return CMD_RET_FAILURE;
+ }
+
+ efi_create_indexed_name(var_name16, var_name16_size, "Boot", id);
+ lo->label = label;
+
+ uridp_len = sizeof(struct efi_device_path) + strlen(argv[3]) + 1;
+ uridp = efi_alloc(uridp_len + sizeof(END));
+ uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+ uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI;
+ uridp->dp.length = uridp_len;
+ strcpy(uridp->uri, argv[3]);
+ pos = (char *)uridp + uridp_len;
+ memcpy(pos, &END, sizeof(END));
+
+ *file_path = &uridp->dp;
+ *fp_size += uridp_len + sizeof(END);
+
+ return CMD_RET_SUCCESS;
+}
+
+/**
* do_efi_boot_add() - set UEFI load option
*
* @cmdtp: Command table
@@ -829,6 +889,21 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
argc -= 1;
argv += 1;
break;
+ case 'u':
+ if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT)) {
+ r = efi_boot_add_uri(argc, argv, var_name16,
+ sizeof(var_name16), &lo,
+ &file_path, &fp_size);
+ if (r != CMD_RET_SUCCESS)
+ goto out;
+ fp_free = file_path;
+ argc -= 3;
+ argv += 3;
+ } else{
+ r = CMD_RET_USAGE;
+ goto out;
+ }
+ break;
default:
r = CMD_RET_USAGE;
goto out;
@@ -1491,6 +1566,9 @@ U_BOOT_LONGHELP(efidebug,
" -b|-B <bootid> <label> <interface> <devnum>[:<part>] <file path>\n"
" -i|-I <interface> <devnum>[:<part>] <initrd file path>\n"
" (-b, -i for short form device path)\n"
+#if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT))
+ " -u <bootid> <label> <uri>\n"
+#endif
" -s '<optional data>'\n"
"efidebug boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n"
" - delete UEFI BootXXXX variables\n"
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index fb16ac743a..6bc9d92285 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -642,6 +642,40 @@ UEFI variables. Booting according to these variables is possible via::
As of U-Boot v2020.10 UEFI variables cannot be set at runtime. The U-Boot
command 'efidebug' can be used to set the variables.
+UEFI HTTP Boot
+~~~~~~~~~~~~~~
+
+HTTP Boot provides the capability for system deployment and configuration
+over the network. HTTP Boot can be activated by specifying::
+
+ CONFIG_EFI_HTTP_BOOT
+
+Enabling that will automatically select::
+
+ CONFIG_CMD_DNS
+ CONFIG_CMD_WGET
+ CONFIG_BLKMAP
+
+Set up the load option specifying the target URI::
+
+ efidebug boot add -u 1 netinst http://foo/bar
+
+When this load option is selected as boot selection, resolve the
+host ip address by dns, then download the file with wget.
+If the downloaded file extension is .iso or .img file, efibootmgr tries to
+mount the image and boot with the default file(e.g. EFI/BOOT/BOOTAA64.EFI).
+If the downloaded file is PE-COFF image, load the downloaded file and
+start it.
+
+The current implementation tries to resolve the IP address as a host name.
+If the uri is like "http://192.168.1.1/foobar",
+the dns process tries to resolve the host "192.168.1.1" and it will
+end up with "host not found".
+
+We need to preset the "httpserverip" environment variable to proceed the wget::
+
+ setenv httpserverip 192.168.1.1
+
Executing the built in hello world application
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index fdcba5c831..fe6a1fcf48 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -15,7 +15,8 @@ obj-$(CONFIG_RKMTD) += rkmtd.o
endif
obj-$(CONFIG_SANDBOX) += sandbox.o host-uclass.o host_dev.o
obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
-obj-$(CONFIG_BLKMAP) += blkmap.o
+obj-$(CONFIG_$(SPL_TPL_)BLKMAP) += blkmap.o
+obj-$(CONFIG_$(SPL_TPL_)BLKMAP) += blkmap_helper.o
obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o
diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c
index 149a4cac3e..21201409ed 100644
--- a/drivers/block/blkmap.c
+++ b/drivers/block/blkmap.c
@@ -66,21 +66,6 @@ struct blkmap_slice {
void (*destroy)(struct blkmap *bm, struct blkmap_slice *bms);
};
-/**
- * struct blkmap - Block map
- *
- * Data associated with a blkmap.
- *
- * @label: Human readable name of this blkmap
- * @blk: Underlying block device
- * @slices: List of slices associated with this blkmap
- */
-struct blkmap {
- char *label;
- struct udevice *blk;
- struct list_head slices;
-};
-
static bool blkmap_slice_contains(struct blkmap_slice *bms, lbaint_t blknr)
{
return (blknr >= bms->blknr) && (blknr < (bms->blknr + bms->blkcnt));
diff --git a/drivers/block/blkmap_helper.c b/drivers/block/blkmap_helper.c
new file mode 100644
index 0000000000..bfba14110d
--- /dev/null
+++ b/drivers/block/blkmap_helper.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * blkmap helper function
+ *
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#include <blk.h>
+#include <blkmap.h>
+#include <dm/device.h>
+#include <dm/device-internal.h>
+
+int blkmap_create_ramdisk(const char *label, ulong image_addr, ulong image_size,
+ struct udevice **devp)
+{
+ int ret;
+ lbaint_t blknum;
+ struct blkmap *bm;
+ struct blk_desc *desc;
+ struct udevice *bm_dev;
+
+ ret = blkmap_create(label, &bm_dev);
+ if (ret) {
+ log_err("failed to create blkmap\n");
+ return ret;
+ }
+
+ bm = dev_get_plat(bm_dev);
+ desc = dev_get_uclass_plat(bm->blk);
+ blknum = image_size >> desc->log2blksz;
+ ret = blkmap_map_pmem(bm_dev, 0, blknum, image_addr);
+ if (ret) {
+ log_err("Unable to map %#llx at block %d : %d\n",
+ (unsigned long long)image_addr, 0, ret);
+ goto err;
+ }
+ log_info("Block %d+0x" LBAF " mapped to %#llx\n", 0, blknum,
+ (unsigned long long)image_addr);
+
+ ret = device_probe(bm->blk);
+ if (ret)
+ goto err;
+
+ if (devp)
+ *devp = bm_dev;
+
+ return 0;
+
+err:
+ blkmap_destroy(bm_dev);
+
+ return ret;
+}
diff --git a/include/blkmap.h b/include/blkmap.h
index af54583c7d..30dc84a7da 100644
--- a/include/blkmap.h
+++ b/include/blkmap.h
@@ -7,6 +7,23 @@
#ifndef _BLKMAP_H
#define _BLKMAP_H
+#include <dm/lists.h>
+
+/**
+ * struct blkmap - Block map
+ *
+ * Data associated with a blkmap.
+ *
+ * @label: Human readable name of this blkmap
+ * @blk: Underlying block device
+ * @slices: List of slices associated with this blkmap
+ */
+struct blkmap {
+ char *label;
+ struct udevice *blk;
+ struct list_head slices;
+};
+
/**
* blkmap_map_linear() - Map region of other block device
*
@@ -74,4 +91,16 @@ int blkmap_create(const char *label, struct udevice **devp);
*/
int blkmap_destroy(struct udevice *dev);
+/**
+ * blkmap_create_ramdisk() - Create new ramdisk with blkmap
+ *
+ * @label: Label of the new blkmap
+ * @image_addr: Target memory start address of this mapping
+ * @image_size: Target memory size of this mapping
+ * @devp: Updated with the address of the created blkmap device
+ * Returns: 0 on success, negative error code on failure
+ */
+int blkmap_create_ramdisk(const char *label, ulong image_addr, ulong image_size,
+ struct udevice **devp);
+
#endif /* _BLKMAP_H */
diff --git a/include/efi_api.h b/include/efi_api.h
index 8f5ef5f680..0e92cb8a7f 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -192,7 +192,7 @@ struct efi_boot_services {
struct efi_event *event,
void *context),
void *notify_context,
- efi_guid_t *event_group,
+ const efi_guid_t *event_group,
struct efi_event **event);
};
@@ -404,6 +404,9 @@ struct efi_runtime_services {
#define EFI_EVENT_GROUP_RESET_SYSTEM \
EFI_GUID(0x62da6a56, 0x13fb, 0x485a, 0xa8, 0xda, \
0xa3, 0xdd, 0x79, 0x12, 0xcb, 0x6b)
+#define EFI_EVENT_GROUP_RETURN_TO_EFIBOOTMGR \
+ EFI_GUID(0xb4a40fe6, 0x9149, 0x4f29, 0x94, 0x47, \
+ 0x49, 0x38, 0x7a, 0x7f, 0xab, 0x87)
/* EFI Configuration Table and GUID definitions */
#define NULL_GUID \
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 247be060e1..664dae28f8 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -289,6 +289,8 @@ extern const efi_guid_t efi_guid_event_group_memory_map_change;
extern const efi_guid_t efi_guid_event_group_ready_to_boot;
/* event group ResetSystem() invoked (before ExitBootServices) */
extern const efi_guid_t efi_guid_event_group_reset_system;
+/* event group return to efibootmgr */
+extern const efi_guid_t efi_guid_event_group_return_to_efibootmgr;
/* GUID of the device tree table */
extern const efi_guid_t efi_guid_fdt;
extern const efi_guid_t efi_guid_loaded_image;
@@ -684,7 +686,7 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
struct efi_event *event,
void *context),
- void *notify_context, efi_guid_t *group,
+ void *notify_context, const efi_guid_t *group,
struct efi_event **event);
/* Call this to set a timer */
efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
diff --git a/include/net.h b/include/net.h
index e63a946002..ac511eab10 100644
--- a/include/net.h
+++ b/include/net.h
@@ -930,4 +930,21 @@ void eth_set_enable_bootdevs(bool enable);
static inline void eth_set_enable_bootdevs(bool enable) {}
#endif
+/**
+ * wget_with_dns() - runs dns host IP address resulution before wget
+ *
+ * @dst_addr: destination address to download the file
+ * @uri: uri string of target file of wget
+ * Return: downloaded file size, negative if failed
+ */
+int wget_with_dns(ulong dst_addr, char *uri);
+
+/**
+ * wget_validate_uri() - varidate the uri
+ *
+ * @uri: uri string of target file of wget
+ * Return: true if uri is valid, false if uri is invalid
+ */
+bool wget_validate_uri(char *uri);
+
#endif /* __NET_H__ */
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 547dfd76ef..2913d1c9df 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -477,4 +477,13 @@ config EFI_RISCV_BOOT_PROTOCOL
replace the transfer via the device-tree. The latter is not
possible on systems using ACPI.
+config EFI_HTTP_BOOT
+ bool "EFI HTTP Boot support"
+ select CMD_DNS
+ select CMD_WGET
+ select BLKMAP
+ help
+ Enabling this option adds EFI HTTP Boot support. It allows to
+ directly boot from network.
+
endif
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index a40762c74c..48153bd5ff 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -7,10 +7,14 @@
#define LOG_CATEGORY LOGC_EFI
+#include <blk.h>
+#include <blkmap.h>
#include <common.h>
#include <charset.h>
+#include <dm.h>
#include <log.h>
#include <malloc.h>
+#include <net.h>
#include <efi_default_filename.h>
#include <efi_loader.h>
#include <efi_variable.h>
@@ -19,6 +23,23 @@
static const struct efi_boot_services *bs;
static const struct efi_runtime_services *rs;
+/**
+ * struct uridp_context - uri device path resource
+ *
+ * @image_size: image size
+ * @image_addr: image address
+ * @loaded_dp: pointer to loaded device path
+ * @ramdisk_blk_dev: pointer to the ramdisk blk device
+ * @mem_handle: efi_handle to the loaded PE-COFF image
+ */
+struct uridp_context {
+ ulong image_size;
+ ulong image_addr;
+ struct efi_device_path *loaded_dp;
+ struct udevice *ramdisk_blk_dev;
+ efi_handle_t mem_handle;
+};
+
const efi_guid_t efi_guid_bootmenu_auto_generated =
EFICONFIG_AUTO_GENERATED_ENTRY_GUID;
@@ -169,6 +190,364 @@ out:
}
/**
+ * mount_image() - mount the image with blkmap
+ *
+ * @lo_label: u16 label string of load option
+ * @addr: image address
+ * @size: image size
+ * Return: pointer to the UCLASS_BLK udevice, NULL if failed
+ */
+static struct udevice *mount_image(u16 *lo_label, ulong addr, ulong size)
+{
+ int err;
+ struct blkmap *bm;
+ struct udevice *bm_dev;
+ char *label = NULL, *p;
+
+ label = efi_alloc(utf16_utf8_strlen(lo_label) + 1);
+ if (!label)
+ return NULL;
+
+ p = label;
+ utf16_utf8_strcpy(&p, lo_label);
+ err = blkmap_create_ramdisk(label, addr, size, &bm_dev);
+ if (err) {
+ efi_free_pool(label);
+ return NULL;
+ }
+ bm = dev_get_plat(bm_dev);
+
+ efi_free_pool(label);
+
+ return bm->blk;
+}
+
+/**
+ * search_default_file() - search default file
+ *
+ * @dev: pointer to the UCLASS_BLK or UCLASS_PARTITION udevice
+ * @loaded_dp: pointer to default file device path
+ * Return: status code
+ */
+static efi_status_t search_default_file(struct udevice *dev,
+ struct efi_device_path **loaded_dp)
+{
+ efi_status_t ret;
+ efi_handle_t handle;
+ u16 *default_file_name = NULL;
+ struct efi_file_handle *root, *f;
+ struct efi_device_path *dp = NULL, *fp = NULL;
+ struct efi_simple_file_system_protocol *file_system;
+ struct efi_device_path *device_path, *full_path = NULL;
+
+ if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) {
+ log_warning("DM_TAG_EFI not found\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ret = EFI_CALL(bs->open_protocol(handle, &efi_guid_device_path,
+ (void **)&device_path, efi_root, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ ret = EFI_CALL(bs->open_protocol(handle, &efi_simple_file_system_protocol_guid,
+ (void **)&file_system, efi_root, NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ ret = EFI_CALL(file_system->open_volume(file_system, &root));
+ if (ret != EFI_SUCCESS)
+ return ret;
+
+ full_path = expand_media_path(device_path);
+ ret = efi_dp_split_file_path(full_path, &dp, &fp);
+ if (ret != EFI_SUCCESS)
+ goto err;
+
+ default_file_name = efi_dp_str(fp);
+ efi_free_pool(dp);
+ efi_free_pool(fp);
+ if (!default_file_name) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto err;
+ }
+
+ ret = EFI_CALL(root->open(root, &f, default_file_name,
+ EFI_FILE_MODE_READ, 0));
+ efi_free_pool(default_file_name);
+ if (ret != EFI_SUCCESS)
+ goto err;
+
+ EFI_CALL(f->close(f));
+ EFI_CALL(root->close(root));
+
+ *loaded_dp = full_path;
+
+ return EFI_SUCCESS;
+
+err:
+ EFI_CALL(root->close(root));
+ efi_free_pool(full_path);
+
+ return ret;
+}
+
+/**
+ * check_disk_has_default_file() - load the default file
+ *
+ * @blk: pointer to the UCLASS_BLK udevice
+ * @dp: pointer to default file device path
+ * Return: status code
+ */
+static efi_status_t check_disk_has_default_file(struct udevice *blk,
+ struct efi_device_path **dp)
+{
+ efi_status_t ret;
+ struct udevice *partition;
+
+ /* image that has no partition table but a file system */
+ ret = search_default_file(blk, dp);
+ if (ret == EFI_SUCCESS)
+ return ret;
+
+ /* try the partitions */
+ device_foreach_child(partition, blk) {
+ enum uclass_id id;
+
+ id = device_get_uclass_id(partition);
+ if (id != UCLASS_PARTITION)
+ continue;
+
+ ret = search_default_file(partition, dp);
+ if (ret == EFI_SUCCESS)
+ return ret;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ * prepare_loaded_image() - prepare ramdisk for downloaded image
+ *
+ * @label: label of load option
+ * @addr: image address
+ * @size: image size
+ * @dp: pointer to default file device path
+ * @blk: pointer to created blk udevice
+ * Return: status code
+ */
+static efi_status_t prepare_loaded_image(u16 *label, ulong addr, ulong size,
+ struct efi_device_path **dp,
+ struct udevice **blk)
+{
+ efi_status_t ret;
+ struct udevice *ramdisk_blk;
+
+ ramdisk_blk = mount_image(label, addr, size);
+ if (!ramdisk_blk)
+ return EFI_LOAD_ERROR;
+
+ ret = check_disk_has_default_file(ramdisk_blk, dp);
+ if (ret != EFI_SUCCESS) {
+ log_info("Cannot boot from downloaded image\n");
+ goto err;
+ }
+
+ /*
+ * TODO: expose the ramdisk to OS.
+ * Need to pass the ramdisk information by the architecture-specific
+ * methods such as 'pmem' device-tree node.
+ */
+ ret = efi_add_memory_map(addr, size, EFI_RESERVED_MEMORY_TYPE);
+ if (ret != EFI_SUCCESS) {
+ log_err("Memory reservation failed\n");
+ goto err;
+ }
+
+ *blk = ramdisk_blk;
+
+ return EFI_SUCCESS;
+
+err:
+ if (blkmap_destroy(ramdisk_blk->parent))
+ log_err("Destroying blkmap failed\n");
+
+ return ret;
+}
+
+/**
+ * efi_bootmgr_release_uridp_resource() - cleanup uri device path resource
+ *
+ * @ctx: event context
+ * Return: status code
+ */
+efi_status_t efi_bootmgr_release_uridp_resource(struct uridp_context *ctx)
+{
+ efi_status_t ret = EFI_SUCCESS;
+
+ if (!ctx)
+ return ret;
+
+ /* cleanup for iso or img image */
+ if (ctx->ramdisk_blk_dev) {
+ ret = efi_add_memory_map(ctx->image_addr, ctx->image_size,
+ EFI_CONVENTIONAL_MEMORY);
+ if (ret != EFI_SUCCESS)
+ log_err("Reclaiming memory failed\n");
+
+ if (blkmap_destroy(ctx->ramdisk_blk_dev->parent)) {
+ log_err("Destroying blkmap failed\n");
+ ret = EFI_DEVICE_ERROR;
+ }
+ }
+
+ /* cleanup for PE-COFF image */
+ if (ctx->mem_handle) {
+ ret = efi_uninstall_multiple_protocol_interfaces(
+ ctx->mem_handle, &efi_guid_device_path, ctx->loaded_dp,
+ NULL);
+ if (ret != EFI_SUCCESS)
+ log_err("Uninstall device_path protocol failed\n");
+ }
+
+ efi_free_pool(ctx->loaded_dp);
+ free(ctx);
+
+ return ret;
+}
+
+/**
+ * efi_bootmgr_image_return_notify() - return to efibootmgr callback
+ *
+ * @event: the event for which this notification function is registered
+ * @context: event context
+ */
+static void EFIAPI efi_bootmgr_image_return_notify(struct efi_event *event,
+ void *context)
+{
+ efi_status_t ret;
+
+ EFI_ENTRY("%p, %p", event, context);
+ ret = efi_bootmgr_release_uridp_resource(context);
+ EFI_EXIT(ret);
+}
+
+/**
+ * try_load_from_uri_path() - Handle the URI device path
+ *
+ * @uridp: uri device path
+ * @lo_label: label of load option
+ * @handle: pointer to handle for newly installed image
+ * Return: status code
+ */
+static efi_status_t try_load_from_uri_path(struct efi_device_path_uri *uridp,
+ u16 *lo_label,
+ efi_handle_t *handle)
+{
+ char *s;
+ int err;
+ int uri_len;
+ efi_status_t ret;
+ void *source_buffer;
+ efi_uintn_t source_size;
+ struct uridp_context *ctx;
+ struct udevice *blk = NULL;
+ struct efi_event *event = NULL;
+ efi_handle_t mem_handle = NULL;
+ struct efi_device_path *loaded_dp;
+ static ulong image_size, image_addr;
+
+ ctx = calloc(1, sizeof(struct uridp_context));
+ if (!ctx)
+ return EFI_OUT_OF_RESOURCES;
+
+ s = env_get("loadaddr");
+ if (!s) {
+ log_err("Error: loadaddr is not set\n");
+ ret = EFI_INVALID_PARAMETER;
+ goto err;
+ }
+
+ image_addr = hextoul(s, NULL);
+ err = wget_with_dns(image_addr, uridp->uri);
+ if (err < 0) {
+ ret = EFI_INVALID_PARAMETER;
+ goto err;
+ }
+
+ image_size = env_get_hex("filesize", 0);
+ if (!image_size) {
+ ret = EFI_INVALID_PARAMETER;
+ goto err;
+ }
+
+ /*
+ * If the file extension is ".iso" or ".img", mount it and try to load
+ * the default file.
+ * If the file is PE-COFF image, load the downloaded file.
+ */
+ uri_len = strlen(uridp->uri);
+ if (!strncmp(&uridp->uri[uri_len - 4], ".iso", 4) ||
+ !strncmp(&uridp->uri[uri_len - 4], ".img", 4)) {
+ ret = prepare_loaded_image(lo_label, image_addr, image_size,
+ &loaded_dp, &blk);
+ if (ret != EFI_SUCCESS)
+ goto err;
+
+ source_buffer = NULL;
+ source_size = 0;
+ } else if (efi_check_pe((void *)image_addr, image_size, NULL) == EFI_SUCCESS) {
+ /*
+ * loaded_dp must exist until efi application returns,
+ * will be freed in return_to_efibootmgr event callback.
+ */
+ loaded_dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
+ (uintptr_t)image_addr, image_size);
+ ret = efi_install_multiple_protocol_interfaces(
+ &mem_handle, &efi_guid_device_path, loaded_dp, NULL);
+ if (ret != EFI_SUCCESS)
+ goto err;
+
+ source_buffer = (void *)image_addr;
+ source_size = image_size;
+ } else {
+ log_err("Error: file type is not supported\n");
+ ret = EFI_UNSUPPORTED;
+ goto err;
+ }
+
+ ctx->image_size = image_size;
+ ctx->image_addr = image_addr;
+ ctx->loaded_dp = loaded_dp;
+ ctx->ramdisk_blk_dev = blk;
+ ctx->mem_handle = mem_handle;
+
+ ret = EFI_CALL(efi_load_image(false, efi_root, loaded_dp, source_buffer,
+ source_size, handle));
+ if (ret != EFI_SUCCESS)
+ goto err;
+
+ /* create event for cleanup when the image returns or error occurs */
+ ret = efi_create_event(EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+ efi_bootmgr_image_return_notify, ctx,
+ &efi_guid_event_group_return_to_efibootmgr,
+ &event);
+ if (ret != EFI_SUCCESS) {
+ log_err("Creating event failed\n");
+ goto err;
+ }
+
+ return ret;
+
+err:
+ efi_bootmgr_release_uridp_resource(ctx);
+
+ return ret;
+}
+
+/**
* try_load_entry() - try to load image for boot option
*
* Attempt to load load-option number 'n', returning device_path and file_path
@@ -211,6 +590,13 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
if (EFI_DP_TYPE(lo.file_path, MEDIA_DEVICE, FILE_PATH)) {
/* file_path doesn't contain a device path */
ret = try_load_from_short_path(lo.file_path, handle);
+ } else if (EFI_DP_TYPE(lo.file_path, MESSAGING_DEVICE, MSG_URI)) {
+ if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT))
+ ret = try_load_from_uri_path(
+ (struct efi_device_path_uri *)lo.file_path,
+ lo.label, handle);
+ else
+ ret = EFI_LOAD_ERROR;
} else {
file_path = expand_media_path(lo.file_path);
ret = EFI_CALL(efi_load_image(true, efi_root, file_path,
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 0b7579cb5a..3767fa2db4 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -90,6 +90,9 @@ const efi_guid_t efi_guid_event_group_ready_to_boot =
/* event group ResetSystem() invoked (before ExitBootServices) */
const efi_guid_t efi_guid_event_group_reset_system =
EFI_EVENT_GROUP_RESET_SYSTEM;
+/* event group return to efibootmgr */
+const efi_guid_t efi_guid_event_group_return_to_efibootmgr =
+ EFI_EVENT_GROUP_RETURN_TO_EFIBOOTMGR;
/* GUIDs of the Load File and Load File2 protocols */
const efi_guid_t efi_guid_load_file_protocol = EFI_LOAD_FILE_PROTOCOL_GUID;
const efi_guid_t efi_guid_load_file2_protocol = EFI_LOAD_FILE2_PROTOCOL_GUID;
@@ -712,7 +715,7 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
void (EFIAPI *notify_function) (
struct efi_event *event,
void *context),
- void *notify_context, efi_guid_t *group,
+ void *notify_context, const efi_guid_t *group,
struct efi_event **event)
{
struct efi_event *evt;
@@ -790,7 +793,7 @@ efi_status_t EFIAPI efi_create_event_ex(uint32_t type, efi_uintn_t notify_tpl,
struct efi_event *event,
void *context),
void *notify_context,
- efi_guid_t *event_group,
+ const efi_guid_t *event_group,
struct efi_event **event)
{
efi_status_t ret;
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index f0d76113b0..b808a7fe62 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -690,6 +690,13 @@ int efi_disk_probe(void *ctx, struct event *event)
return -1;
}
+ /* only do the boot option management when UEFI sub-system is initialized */
+ if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) && efi_obj_list_initialized == EFI_SUCCESS) {
+ ret = efi_bootmgr_update_media_device_boot_option();
+ if (ret != EFI_SUCCESS)
+ return -1;
+ }
+
return 0;
}
@@ -742,6 +749,17 @@ int efi_disk_remove(void *ctx, struct event *event)
dev_tag_del(dev, DM_TAG_EFI);
return 0;
+
+ /*
+ * TODO A flag to distinguish below 2 different scenarios of this
+ * function call is needed:
+ * a) Unplugging of a removable media under U-Boot
+ * b) U-Boot exiting and booting an OS
+ * In case of scenario a), efi_bootmgr_update_media_device_boot_option()
+ * needs to be invoked here to update the boot options and remove the
+ * unnecessary ones.
+ */
+
}
/**
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index e6de685e87..37359a77bb 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -245,6 +245,13 @@ efi_status_t efi_init_obj_list(void)
if (ret != EFI_SUCCESS)
goto out;
+ if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
+ /* update boot option after variable service initialized */
+ ret = efi_bootmgr_update_media_device_boot_option();
+ if (ret != EFI_SUCCESS)
+ goto out;
+ }
+
/* Define supported languages */
ret = efi_init_platform_lang();
if (ret != EFI_SUCCESS)
diff --git a/net/wget.c b/net/wget.c
index 8bb4d72db1..6ae2237a0a 100644
--- a/net/wget.c
+++ b/net/wget.c
@@ -4,15 +4,20 @@
* Copyright Duncan Hare <dh@synoia.com> 2017
*/
+#include <asm/global_data.h>
#include <command.h>
#include <common.h>
#include <display_options.h>
#include <env.h>
#include <image.h>
+#include <lmb.h>
#include <mapmem.h>
#include <net.h>
#include <net/tcp.h>
#include <net/wget.h>
+#include <stdlib.h>
+
+DECLARE_GLOBAL_DATA_PTR;
static const char bootfile1[] = "GET ";
static const char bootfile3[] = " HTTP/1.0\r\n\r\n";
@@ -56,6 +61,29 @@ static unsigned int retry_tcp_ack_num; /* TCP retry acknowledge number*/
static unsigned int retry_tcp_seq_num; /* TCP retry sequence number */
static int retry_len; /* TCP retry length */
+static ulong wget_load_size;
+
+/**
+ * wget_init_max_size() - initialize maximum load size
+ *
+ * Return: 0 if success, -1 if fails
+ */
+static int wget_init_load_size(void)
+{
+ struct lmb lmb;
+ phys_size_t max_size;
+
+ lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
+
+ max_size = lmb_get_free_size(&lmb, image_load_addr);
+ if (!max_size)
+ return -1;
+
+ wget_load_size = max_size;
+
+ return 0;
+}
+
/**
* store_block() - store block in memory
* @src: source of data
@@ -64,10 +92,25 @@ static int retry_len; /* TCP retry length */
*/
static inline int store_block(uchar *src, unsigned int offset, unsigned int len)
{
+ ulong store_addr = image_load_addr + offset;
ulong newsize = offset + len;
uchar *ptr;
- ptr = map_sysmem(image_load_addr + offset, len);
+ if (IS_ENABLED(CONFIG_LMB)) {
+ ulong end_addr = image_load_addr + wget_load_size;
+
+ if (!end_addr)
+ end_addr = ULONG_MAX;
+
+ if (store_addr < image_load_addr ||
+ store_addr + len > end_addr) {
+ printf("\nwget error: ");
+ printf("trying to overwrite reserved memory...\n");
+ return -1;
+ }
+ }
+
+ ptr = map_sysmem(store_addr, len);
memcpy(ptr, src, len);
unmap_sysmem(ptr);
@@ -248,25 +291,39 @@ static void wget_connected(uchar *pkt, unsigned int tcp_seq_num,
net_boot_file_size = 0;
- if (len > hlen)
- store_block(pkt + hlen, 0, len - hlen);
+ if (len > hlen) {
+ if (store_block(pkt + hlen, 0, len - hlen) != 0) {
+ wget_loop_state = NETLOOP_FAIL;
+ wget_fail("wget: store error\n", tcp_seq_num, tcp_ack_num, action);
+ net_set_state(NETLOOP_FAIL);
+ return;
+ }
+ }
debug_cond(DEBUG_WGET,
"wget: Connected Pkt %p hlen %x\n",
pkt, hlen);
for (i = 0; i < pkt_q_idx; i++) {
+ int err;
+
ptr1 = map_sysmem(
(phys_addr_t)(pkt_q[i].pkt),
pkt_q[i].len);
- store_block(ptr1,
- pkt_q[i].tcp_seq_num -
- initial_data_seq_num,
- pkt_q[i].len);
+ err = store_block(ptr1,
+ pkt_q[i].tcp_seq_num -
+ initial_data_seq_num,
+ pkt_q[i].len);
unmap_sysmem(ptr1);
debug_cond(DEBUG_WGET,
"wget: Connctd pkt Q %p len %x\n",
pkt_q[i].pkt, pkt_q[i].len);
+ if (err) {
+ wget_loop_state = NETLOOP_FAIL;
+ wget_fail("wget: store error\n", tcp_seq_num, tcp_ack_num, action);
+ net_set_state(NETLOOP_FAIL);
+ return;
+ }
}
}
}
@@ -338,6 +395,7 @@ static void wget_handler(uchar *pkt, u16 dport,
len) != 0) {
wget_fail("wget: store error\n",
tcp_seq_num, tcp_ack_num, action);
+ net_set_state(NETLOOP_FAIL);
return;
}
@@ -428,6 +486,15 @@ void wget_start(void)
debug_cond(DEBUG_WGET,
"\nwget:Load address: 0x%lx\nLoading: *\b", image_load_addr);
+ if (IS_ENABLED(CONFIG_LMB)) {
+ if (wget_init_load_size()) {
+ printf("\nwget error: ");
+ printf("trying to overwrite reserved memory...\n");
+ net_set_state(NETLOOP_FAIL);
+ return;
+ }
+ }
+
net_set_timeout_handler(wget_timeout, wget_timeout_handler);
tcp_set_tcp_handler(wget_handler);
@@ -446,3 +513,127 @@ void wget_start(void)
wget_send(TCP_SYN, 0, 0, 0);
}
+
+#if (IS_ENABLED(CONFIG_CMD_DNS))
+int wget_with_dns(ulong dst_addr, char *uri)
+{
+ int ret;
+ char *s, *host_name, *file_name, *str_copy;
+
+ /*
+ * Download file using wget.
+ *
+ * U-Boot wget takes the target uri in this format.
+ * "<http server ip>:<file path>" e.g.) 192.168.1.1:/sample/test.iso
+ * Need to resolve the http server ip address before starting wget.
+ */
+ str_copy = strdup(uri);
+ if (!str_copy)
+ return -ENOMEM;
+
+ s = str_copy + strlen("http://");
+ host_name = strsep(&s, "/");
+ if (!s) {
+ log_err("Error: invalied uri, no file path\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ file_name = s;
+
+ /* TODO: If the given uri has ip address for the http server, skip dns */
+ net_dns_resolve = host_name;
+ net_dns_env_var = "httpserverip";
+ if (net_loop(DNS) < 0) {
+ log_err("Error: dns lookup of %s failed, check setup\n", net_dns_resolve);
+ ret = -EINVAL;
+ goto out;
+ }
+ s = env_get("httpserverip");
+ if (!s) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ strlcpy(net_boot_file_name, s, sizeof(net_boot_file_name));
+ strlcat(net_boot_file_name, ":/", sizeof(net_boot_file_name)); /* append '/' which is removed by strsep() */
+ strlcat(net_boot_file_name, file_name, sizeof(net_boot_file_name));
+ image_load_addr = dst_addr;
+ ret = net_loop(WGET);
+
+out:
+ free(str_copy);
+
+ return ret;
+}
+#endif
+
+/**
+ * wget_validate_uri() - validate the uri for wget
+ *
+ * @uri: uri string
+ *
+ * This function follows the current U-Boot wget implementation.
+ * scheme: only "http:" is supported
+ * authority:
+ * - user information: not supported
+ * - host: supported
+ * - port: not supported(always use the default port)
+ *
+ * Uri is expected to be correctly percent encoded.
+ * This is the minimum check, control codes(0x1-0x19, 0x7F, except '\0')
+ * and space character(0x20) are not allowed.
+ *
+ * TODO: stricter uri conformance check
+ *
+ * Return: true on success, false on failure
+ */
+bool wget_validate_uri(char *uri)
+{
+ char c;
+ bool ret = true;
+ char *str_copy, *s, *authority;
+
+ for (c = 0x1; c < 0x21; c++) {
+ if (strchr(uri, c)) {
+ log_err("invalid character is used\n");
+ return false;
+ }
+ }
+ if (strchr(uri, 0x7f)) {
+ log_err("invalid character is used\n");
+ return false;
+ }
+
+ if (strncmp(uri, "http://", 7)) {
+ log_err("only http:// is supported\n");
+ return false;
+ }
+ str_copy = strdup(uri);
+ if (!str_copy)
+ return false;
+
+ s = str_copy + strlen("http://");
+ authority = strsep(&s, "/");
+ if (!s) {
+ log_err("invalid uri, no file path\n");
+ ret = false;
+ goto out;
+ }
+ s = strchr(authority, '@');
+ if (s) {
+ log_err("user information is not supported\n");
+ ret = false;
+ goto out;
+ }
+ s = strchr(authority, ':');
+ if (s) {
+ log_err("user defined port is not supported\n");
+ ret = false;
+ goto out;
+ }
+
+out:
+ free(str_copy);
+
+ return ret;
+}
diff --git a/test/py/tests/test_efi_secboot/test_signed.py b/test/py/tests/test_efi_secboot/test_signed.py
index ca52e853d8..2f862a259a 100644
--- a/test/py/tests/test_efi_secboot/test_signed.py
+++ b/test/py/tests/test_efi_secboot/test_signed.py
@@ -29,7 +29,7 @@ class TestEfiSignedImage(object):
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
'efidebug boot add -b 1 HELLO1 host 0:1 /helloworld.efi.signed -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -37,7 +37,7 @@ class TestEfiSignedImage(object):
# Test Case 1b, run unsigned image if no PK
output = u_boot_console.run_command_list([
'efidebug boot add -b 2 HELLO2 host 0:1 /helloworld.efi -s ""',
- 'efidebug boot next 2',
+ 'efidebug boot order 2',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -59,13 +59,13 @@ class TestEfiSignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO1 host 0:1 /helloworld.efi.signed -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert('\'HELLO1\' failed' in ''.join(output))
assert('efi_start_image() returned: 26' in ''.join(output))
output = u_boot_console.run_command_list([
'efidebug boot add -b 2 HELLO2 host 0:1 /helloworld.efi -s ""',
- 'efidebug boot next 2',
+ 'efidebug boot order 2',
'efidebug test bootmgr'])
assert '\'HELLO2\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -77,12 +77,12 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize db'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 2',
+ 'efidebug boot order 2',
'efidebug test bootmgr'])
assert '\'HELLO2\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -105,7 +105,7 @@ class TestEfiSignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -117,7 +117,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize db'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -143,7 +143,7 @@ class TestEfiSignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -170,7 +170,7 @@ class TestEfiSignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed_2sigs -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -181,7 +181,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -a -i 4000000:$filesize db'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -193,7 +193,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -205,7 +205,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -a -i 4000000:$filesize dbx'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -230,7 +230,7 @@ class TestEfiSignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed_2sigs -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -254,7 +254,7 @@ class TestEfiSignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -265,7 +265,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -279,7 +279,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -307,7 +307,7 @@ class TestEfiSignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed_2sigs -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -330,7 +330,7 @@ class TestEfiSignedImage(object):
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi.signed_2sigs -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -349,7 +349,7 @@ class TestEfiSignedImage(object):
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
'efidebug boot add -b 1 HELLO1 host 0:1 /helloworld_forged.efi.signed -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert('hELLO, world!' in ''.join(output))
@@ -364,7 +364,7 @@ class TestEfiSignedImage(object):
'setenv -e -nv -bs -rt -at -i 4000000:$filesize PK'])
assert 'Failed to set EFI variable' not in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert(not 'hELLO, world!' in ''.join(output))
assert('\'HELLO1\' failed' in ''.join(output))
diff --git a/test/py/tests/test_efi_secboot/test_signed_intca.py b/test/py/tests/test_efi_secboot/test_signed_intca.py
index d8d599d22f..8d9a5f3e7f 100644
--- a/test/py/tests/test_efi_secboot/test_signed_intca.py
+++ b/test/py/tests/test_efi_secboot/test_signed_intca.py
@@ -40,7 +40,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO_a host 0:1 /helloworld.efi.signed_a -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO_a\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -49,7 +49,7 @@ class TestEfiSignedImageIntca(object):
# Test Case 1b, signed and authenticated by root CA
output = u_boot_console.run_command_list([
'efidebug boot add -b 2 HELLO_ab host 0:1 /helloworld.efi.signed_ab -s ""',
- 'efidebug boot next 2',
+ 'efidebug boot order 2',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -71,7 +71,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -81,7 +81,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'fatload host 0:1 4000000 db_b.auth',
'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
@@ -91,7 +91,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'fatload host 0:1 4000000 db_c.auth',
'setenv -e -nv -bs -rt -at -i 4000000:$filesize db',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -117,7 +117,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert 'Hello, world!' in ''.join(output)
# Or,
@@ -129,7 +129,7 @@ class TestEfiSignedImageIntca(object):
output = u_boot_console.run_command_list([
'fatload host 0:1 4000000 dbx_c.auth',
'setenv -e -nv -bs -rt -at -i 4000000:$filesize dbx',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert '\'HELLO_abc\' failed' in ''.join(output)
assert 'efi_start_image() returned: 26' in ''.join(output)
diff --git a/test/py/tests/test_efi_secboot/test_unsigned.py b/test/py/tests/test_efi_secboot/test_unsigned.py
index df63f0df08..7c078f220d 100644
--- a/test/py/tests/test_efi_secboot/test_unsigned.py
+++ b/test/py/tests/test_efi_secboot/test_unsigned.py
@@ -36,11 +36,11 @@ class TestEfiUnsignedImage(object):
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert 'efi_start_image() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
@@ -65,7 +65,7 @@ class TestEfiUnsignedImage(object):
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'bootefi bootmgr'])
assert 'Hello, world!' in ''.join(output)
@@ -89,11 +89,11 @@ class TestEfiUnsignedImage(object):
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert 'efi_start_image() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
@@ -107,11 +107,11 @@ class TestEfiUnsignedImage(object):
output = u_boot_console.run_command_list([
'efidebug boot add -b 1 HELLO host 0:1 /helloworld.efi -s ""',
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'bootefi bootmgr'])
assert '\'HELLO\' failed' in ''.join(output)
output = u_boot_console.run_command_list([
- 'efidebug boot next 1',
+ 'efidebug boot order 1',
'efidebug test bootmgr'])
assert 'efi_start_image() returned: 26' in ''.join(output)
assert 'Hello, world!' not in ''.join(output)
diff --git a/test/py/tests/test_fs/test_erofs.py b/test/py/tests/test_fs/test_erofs.py
index 458a52ba79..87ad8f2d5f 100644
--- a/test/py/tests/test_fs/test_erofs.py
+++ b/test/py/tests/test_fs/test_erofs.py
@@ -196,6 +196,15 @@ def test_erofs(u_boot_console):
"""
build_dir = u_boot_console.config.build_dir
+ # If the EFI subsystem is enabled and initialized, EFI subsystem tries to
+ # add EFI boot option when the new disk is detected. If there is no EFI
+ # System Partition exists, EFI subsystem outputs error messages and
+ # it ends up with test failure.
+ # Restart U-Boot to clear the previous state.
+ # TODO: Ideally EFI test cases need to be fixed, but it will
+ # increase the number of system reset.
+ u_boot_console.restart_uboot()
+
try:
# setup test environment
make_erofs_image(build_dir)
diff --git a/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py b/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py
index 527a556ed8..a20a7d1a66 100644
--- a/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py
+++ b/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py
@@ -118,6 +118,15 @@ def test_sqfs_ls(u_boot_console):
"""
build_dir = u_boot_console.config.build_dir
+ # If the EFI subsystem is enabled and initialized, EFI subsystem tries to
+ # add EFI boot option when the new disk is detected. If there is no EFI
+ # System Partition exists, EFI subsystem outputs error messages and
+ # it ends up with test failure.
+ # Restart U-Boot to clear the previous state.
+ # TODO: Ideally EFI test cases need to be fixed, but it will
+ # increase the number of system reset.
+ u_boot_console.restart_uboot()
+
# setup test environment
check_mksquashfs_version()
generate_sqfs_src_dir(build_dir)