diff --git a/Makefile b/Makefile index 8b030f31be..444baaefd0 100644 --- a/Makefile +++ b/Makefile @@ -2160,7 +2160,7 @@ CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h \ mkimage-out.spl.mkimage mkimage.spl.mkimage imx-boot.map \ itb.fit.fit itb.fit.itb itb.map spl.map mkimage-out.rom.mkimage \ mkimage.rom.mkimage rom.map simple-bin.map simple-bin-spi.map \ - idbloader-spi.img + idbloader-spi.img lib/efi_loader/helloworld_efi.S # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config include/generated spl tpl \ diff --git a/boot/bootm.c b/boot/bootm.c index 4144ff3b03..75f0b4a9af 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -240,7 +240,8 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { if (IS_ENABLED(CONFIG_CMD_BOOTI) && - images.os.arch == IH_ARCH_ARM64) { + images.os.arch == IH_ARCH_ARM64 && + images.os.os == IH_OS_LINUX) { ulong image_addr; ulong image_size; diff --git a/doc/develop/event.rst b/doc/develop/event.rst index 1c1c9ef7f1..cb09e9c85a 100644 --- a/doc/develop/event.rst +++ b/doc/develop/event.rst @@ -28,8 +28,8 @@ To declare a spy, use something like this:: } EVENT_SPY(EVT_DM_POST_INIT_F, snow_setup_cpus); -Your function is called when EVT_DM_POST_INIT_F is emitted, i.e. after driver -model is inited (in SPL, or in U-Boot proper before and after relocation). +This function is called when EVT_DM_POST_INIT_F is emitted, i.e. after the +driver model is initialized (in U-Boot proper before and after relocation). Debugging diff --git a/doc/usage/cmd/imxtract.rst b/doc/usage/cmd/imxtract.rst new file mode 100644 index 0000000000..eb64b1cefa --- /dev/null +++ b/doc/usage/cmd/imxtract.rst @@ -0,0 +1,81 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +imxtract command +================ + +Synopsis +-------- + +:: + + imxtract addr part [dest] + imxtract addr uname [dest] + +Description +----------- + +The imxtract command is used to extract a part of a multi-image file. + +Two different file formats are supported: + +* FIT images +* legacy U-Boot images + +addr + Address of the multi-image file from which a part shall be extracted + +part + Index (hexadecimal) of the part of a legacy U-Boot image to be extracted + +uname + Name of the part of a FIT image to be extracted + +dest + Destination address (defaults to 0x0) + +The value of environment variable *verify* controls if the hashes and +signatures of FIT images or the check sums of legacy U-Boot images are checked. +To enable checking set *verify* to one of the values *1*, *yes*, *true*. +(Actually only the first letter is checked disregarding the case.) + +To list the parts of an image the *iminfo* command can be used. + +Examples +-------- + +With verify=no incorrect hashes, signatures, or check sums don't stop the +extraction. But correct hashes are still indicated in the output +(here: md5, sha1). + +.. code-block:: console + + => setenv verify no + => imxtract $loadaddr kernel-1 $kernel_addr_r + ## Copying 'kernel-1' subimage from FIT image at 40200000 ... + md5+ sha1+ Loading part 0 ... OK + => + +With verify=yes incorrect hashes, signatures, or check sums stop the extraction. + +.. code-block:: console + + => setenv verify yes + => imxtract $loadaddr kernel-1 $kernel_addr_r + ## Copying 'kernel-1' subimage from FIT image at 40200000 ... + md5 error! + Bad hash value for 'hash-1' hash node in 'kernel-1' image node + Bad Data Hash + => + +Configuration +------------- + +The imxtract command is only available if CONFIG_CMD_XIMG=y. Support for FIT +images requires CONFIG_FIT=y. Support for legacy U-Boot images requires +CONFIG_LEGACY_IMAGE_FORMAT=y. + +Return value +------------ + +On success the return value $? of the command is 0 (true). On failure the +return value is 1 (false). diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 84ef8a9a42..54ef89edb2 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -62,6 +62,7 @@ Shell commands cmd/fwu_mdata cmd/gpio cmd/host + cmd/imxtract cmd/load cmd/loadb cmd/loadm diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index d2256713a8..28c8cdf710 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -690,89 +690,50 @@ int efi_disk_probe(void *ctx, struct event *event) return 0; } -/* - * Delete an efi_disk object for a whole raw disk +/** + * efi_disk_remove - delete an efi_disk object for a block device or partition * - * @dev uclass device (UCLASS_BLK) + * @ctx: event context: driver binding protocol + * @event: EV_PM_PRE_REMOVE event * - * Delete an efi_disk object which is associated with @dev. - * The type of @dev must be UCLASS_BLK. + * Delete an efi_disk object which is associated with the UCLASS_BLK or + * UCLASS_PARTITION device for which the EV_PM_PRE_REMOVE event is raised. * - * @return 0 on success, -1 otherwise - */ -static int efi_disk_delete_raw(struct udevice *dev) -{ - efi_handle_t handle; - struct blk_desc *desc; - struct efi_disk_obj *diskobj; - - if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) - return -1; - - desc = dev_get_uclass_plat(dev); - if (desc->uclass_id != UCLASS_EFI_LOADER) { - diskobj = container_of(handle, struct efi_disk_obj, header); - efi_free_pool(diskobj->dp); - } - - efi_delete_handle(handle); - dev_tag_del(dev, DM_TAG_EFI); - - return 0; -} - -/* - * Delete an efi_disk object for a disk partition - * - * @dev uclass device (UCLASS_PARTITION) - * - * Delete an efi_disk object which is associated with @dev. - * The type of @dev must be UCLASS_PARTITION. - * - * @return 0 on success, -1 otherwise - */ -static int efi_disk_delete_part(struct udevice *dev) -{ - efi_handle_t handle; - struct efi_disk_obj *diskobj; - - if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) - return -1; - - diskobj = container_of(handle, struct efi_disk_obj, header); - - efi_free_pool(diskobj->dp); - efi_delete_handle(handle); - dev_tag_del(dev, DM_TAG_EFI); - - return 0; -} - -/* - * Delete an efi_disk object for a block device - * - * @dev uclass device (UCLASS_BLK or UCLASS_PARTITION) - * - * Delete an efi_disk object which is associated with @dev. - * The type of @dev must be either UCLASS_BLK or UCLASS_PARTITION. - * This function is expected to be called at EV_PM_PRE_REMOVE. - * - * @return 0 on success, -1 otherwise + * Return: 0 on success, -1 otherwise */ int efi_disk_remove(void *ctx, struct event *event) { enum uclass_id id; - struct udevice *dev; + struct udevice *dev = event->data.dm.dev; + efi_handle_t handle; + struct blk_desc *desc; + struct efi_disk_obj *diskobj = NULL; - dev = event->data.dm.dev; - id = device_get_uclass_id(dev); - - if (id == UCLASS_BLK) - return efi_disk_delete_raw(dev); - else if (id == UCLASS_PARTITION) - return efi_disk_delete_part(dev); - else + if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) return 0; + + id = device_get_uclass_id(dev); + switch (id) { + case UCLASS_BLK: + desc = dev_get_uclass_plat(dev); + if (desc && desc->uclass_id != UCLASS_EFI_LOADER) + diskobj = container_of(handle, struct efi_disk_obj, + header); + break; + case UCLASS_PARTITION: + diskobj = container_of(handle, struct efi_disk_obj, header); + break; + default: + return 0; + } + + if (diskobj) + efi_free_pool(diskobj->dp); + + efi_delete_handle(handle); + dev_tag_del(dev, DM_TAG_EFI); + + return 0; } /** diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c index d2bbd1c4f6..63e674bedc 100644 --- a/lib/efi_selftest/efi_selftest_controllers.c +++ b/lib/efi_selftest/efi_selftest_controllers.c @@ -271,6 +271,8 @@ static int setup(const efi_handle_t img_handle, efi_status_t ret; boottime = systable->boottime; + handle_controller = NULL; + handle_driver = NULL; /* Create controller handle */ ret = boottime->install_protocol_interface( @@ -402,14 +404,36 @@ static int execute(void) /* Check number of child controllers */ ret = count_child_controllers(handle_controller, &guid_controller, &count); - if (ret == EFI_SUCCESS) + if (ret == EFI_SUCCESS || count) { efi_st_error("Uninstall failed\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; } + /* + * Tear down unit test. + * + */ +static int teardown(void) +{ + efi_status_t ret; + /* Uninstall binding protocol */ + ret = boottime->uninstall_protocol_interface(handle_driver, + &guid_driver_binding_protocol, + &binding_interface); + if (ret != EFI_SUCCESS) + efi_st_error("Failed to uninstall protocols\n"); + + return ret; +} + EFI_UNIT_TEST(controllers) = { .name = "controllers", .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, .setup = setup, .execute = execute, + .teardown = teardown, }; diff --git a/lib/efi_selftest/efi_selftest_manageprotocols.c b/lib/efi_selftest/efi_selftest_manageprotocols.c index 8edb1e4d46..097b2ae354 100644 --- a/lib/efi_selftest/efi_selftest_manageprotocols.c +++ b/lib/efi_selftest/efi_selftest_manageprotocols.c @@ -79,6 +79,8 @@ static int setup(const efi_handle_t img_handle, efi_status_t ret; efi_handle_t handle; + handle1 = NULL; + handle2 = NULL; boottime = systable->boottime; ret = boottime->install_protocol_interface(&handle1, &guid3, diff --git a/lib/efi_selftest/efi_selftest_register_notify.c b/lib/efi_selftest/efi_selftest_register_notify.c index ad4bcce1a1..adf5dd00a1 100644 --- a/lib/efi_selftest/efi_selftest_register_notify.c +++ b/lib/efi_selftest/efi_selftest_register_notify.c @@ -124,6 +124,7 @@ static int execute(void) { efi_status_t ret; efi_handle_t handle1 = NULL, handle2 = NULL; + struct interface *interface; struct interface interface1, interface2; ret = boottime->install_protocol_interface(&handle1, &guid1, @@ -145,6 +146,18 @@ static int execute(void) efi_st_error("LocateHandle failed\n"); return EFI_ST_FAILURE; } + interface = NULL; + ret = boottime->open_protocol(handle1, &guid1, (void**)&interface, + NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Cannot find installed protocol on handle\n"); + return EFI_ST_FAILURE; + } + if (interface != &interface1) { + efi_st_error("Wrong interface after install\n"); + return EFI_ST_FAILURE; + } ret = boottime->free_pool(context.handles); if (ret != EFI_SUCCESS) { efi_st_error("FreePool failed\n"); @@ -186,6 +199,18 @@ static int execute(void) efi_st_error("FreePool failed\n"); return EFI_ST_FAILURE; } + interface = NULL; + ret = boottime->open_protocol(handle1, &guid1, (void**)&interface, + NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Cannot find reinstalled protocol on handle\n"); + return EFI_ST_FAILURE; + } + if (interface != &interface2) { + efi_st_error("Wrong interface after reinstall\n"); + return EFI_ST_FAILURE; + } context.notify_count = 0; ret = boottime->install_protocol_interface(&handle2, &guid1, EFI_NATIVE_INTERFACE, diff --git a/test/py/tests/test_efi_fit.py b/test/py/tests/test_efi_fit.py index 7b7c98fb04..0ad483500f 100644 --- a/test/py/tests/test_efi_fit.py +++ b/test/py/tests/test_efi_fit.py @@ -431,6 +431,11 @@ def test_efi_fit_launch(u_boot_console): cons = u_boot_console # Array slice removes leading/trailing quotes. sys_arch = cons.config.buildconfig.get('config_sys_arch', '"sandbox"')[1:-1] + if sys_arch == 'arm': + arm64 = cons.config.buildconfig.get('config_arm64') + if arm64: + sys_arch = 'arm64' + is_sandbox = sys_arch == 'sandbox' if is_sandbox: