]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - lib/efi_loader/efi_bootbin.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * For the code moved from cmd/bootefi.c
4 * Copyright (c) 2016 Alexander Graf
7 #define LOG_CATEGORY LOGC_EFI
11 #include <efi_loader.h>
17 static struct efi_device_path
*bootefi_image_path
;
18 static struct efi_device_path
*bootefi_device_path
;
19 static void *image_addr
;
20 static size_t image_size
;
23 * efi_get_image_parameters() - return image parameters
25 * @img_addr: address of loaded image in memory
26 * @img_size: size of loaded image
28 void efi_get_image_parameters(void **img_addr
, size_t *img_size
)
30 *img_addr
= image_addr
;
31 *img_size
= image_size
;
35 * efi_clear_bootdev() - clear boot device
37 void efi_clear_bootdev(void)
39 efi_free_pool(bootefi_device_path
);
40 efi_free_pool(bootefi_image_path
);
41 bootefi_device_path
= NULL
;
42 bootefi_image_path
= NULL
;
48 * efi_set_bootdev() - set boot device
50 * This function is called when a file is loaded, e.g. via the 'load' command.
51 * We use the path to this file to inform the UEFI binary about the boot device.
53 * @dev: device, e.g. "MMC"
54 * @devnr: number of the device, e.g. "1:2"
55 * @path: path to file loaded
56 * @buffer: buffer with file loaded
57 * @buffer_size: size of file loaded
59 void efi_set_bootdev(const char *dev
, const char *devnr
, const char *path
,
60 void *buffer
, size_t buffer_size
)
62 struct efi_device_path
*device
, *image
;
65 log_debug("dev=%s, devnr=%s, path=%s, buffer=%p, size=%zx\n", dev
,
66 devnr
, path
, buffer
, buffer_size
);
68 /* Forget overwritten image */
69 if (buffer
+ buffer_size
>= image_addr
&&
70 image_addr
+ image_size
>= buffer
)
73 /* Remember only PE-COFF and FIT images */
74 if (efi_check_pe(buffer
, buffer_size
, NULL
) != EFI_SUCCESS
) {
75 if (IS_ENABLED(CONFIG_FIT
) &&
76 !fit_check_format(buffer
, IMAGE_SIZE_INVAL
)) {
78 * FIT images of type EFI_OS are started via command
79 * bootm. We should not use their boot device with the
85 log_debug("- not remembering image\n");
90 /* efi_set_bootdev() is typically called repeatedly, recover memory */
94 image_size
= buffer_size
;
96 ret
= efi_dp_from_name(dev
, devnr
, path
, &device
, &image
);
97 if (ret
== EFI_SUCCESS
) {
98 bootefi_device_path
= device
;
100 /* FIXME: image should not contain device */
101 struct efi_device_path
*image_tmp
= image
;
103 efi_dp_split_file_path(image
, &device
, &image
);
104 efi_free_pool(image_tmp
);
106 bootefi_image_path
= image
;
107 log_debug("- boot device %pD\n", device
);
109 log_debug("- image %pD\n", image
);
111 log_debug("- efi_dp_from_name() failed, err=%lx\n", ret
);
117 * efi_run_image() - run loaded UEFI image
119 * @source_buffer: memory address of the UEFI image
120 * @source_size: size of the UEFI image
121 * Return: status code
123 efi_status_t
efi_run_image(void *source_buffer
, efi_uintn_t source_size
)
125 efi_handle_t mem_handle
= NULL
, handle
;
126 struct efi_device_path
*file_path
= NULL
;
127 struct efi_device_path
*msg_path
;
131 if (!bootefi_device_path
|| !bootefi_image_path
) {
132 log_debug("Not loaded from disk\n");
134 * Special case for efi payload not loaded from disk,
135 * such as 'bootefi hello' or for example payload
136 * loaded directly into memory via JTAG, etc:
138 file_path
= efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE
,
139 (uintptr_t)source_buffer
,
142 * Make sure that device for device_path exist
143 * in load_image(). Otherwise, shell and grub will fail.
145 ret
= efi_install_multiple_protocol_interfaces(&mem_handle
,
146 &efi_guid_device_path
,
148 if (ret
!= EFI_SUCCESS
)
150 msg_path
= file_path
;
152 file_path
= efi_dp_concat(bootefi_device_path
,
153 bootefi_image_path
, false);
154 msg_path
= bootefi_image_path
;
155 log_debug("Loaded from disk\n");
158 log_info("Booting %pD\n", msg_path
);
160 ret
= EFI_CALL(efi_load_image(false, efi_root
, file_path
, source_buffer
,
161 source_size
, &handle
));
162 if (ret
!= EFI_SUCCESS
) {
163 log_err("Loading image failed\n");
167 /* Transfer environment variable as load options */
168 ret
= efi_env_set_load_options(handle
, "bootargs", &load_options
);
169 if (ret
!= EFI_SUCCESS
)
172 ret
= do_bootefi_exec(handle
, load_options
);
178 r
= efi_uninstall_multiple_protocol_interfaces(
179 mem_handle
, &efi_guid_device_path
, file_path
, NULL
);
180 if (r
!= EFI_SUCCESS
)
181 log_err("Uninstalling protocol interfaces failed\n");
183 efi_free_pool(file_path
);
189 * efi_binary_run() - run loaded UEFI image
191 * @image: memory address of the UEFI image
192 * @size: size of the UEFI image
195 * Execute an EFI binary image loaded at @image.
196 * @size may be zero if the binary is loaded with U-Boot load command.
198 * Return: status code
200 efi_status_t
efi_binary_run(void *image
, size_t size
, void *fdt
)
204 /* Initialize EFI drivers */
205 ret
= efi_init_obj_list();
206 if (ret
!= EFI_SUCCESS
) {
207 log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
208 ret
& ~EFI_ERROR_MASK
);
212 ret
= efi_install_fdt(fdt
);
213 if (ret
!= EFI_SUCCESS
)
216 return efi_run_image(image
, size
);