|
@@ -206,11 +206,13 @@ static void *get_var(u16 *name, const efi_guid_t *vendor,
|
|
|
* if successful. This checks that the EFI_LOAD_OPTION is active (enabled)
|
|
|
* and that the specified file to boot exists.
|
|
|
*
|
|
|
- * @n: number of the boot option, e.g. 0x0a13 for Boot0A13
|
|
|
- * @handle: on return handle for the newly installed image
|
|
|
- * Return: status code
|
|
|
+ * @n: number of the boot option, e.g. 0x0a13 for Boot0A13
|
|
|
+ * @handle: on return handle for the newly installed image
|
|
|
+ * @load_options: load options set on the loaded image protocol
|
|
|
+ * Return: status code
|
|
|
*/
|
|
|
-static efi_status_t try_load_entry(u16 n, efi_handle_t *handle)
|
|
|
+static efi_status_t try_load_entry(u16 n, efi_handle_t *handle,
|
|
|
+ void **load_options)
|
|
|
{
|
|
|
struct efi_load_option lo;
|
|
|
u16 varname[] = L"Boot0000";
|
|
@@ -250,10 +252,9 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle)
|
|
|
|
|
|
attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
|
|
EFI_VARIABLE_RUNTIME_ACCESS;
|
|
|
- size = sizeof(n);
|
|
|
ret = efi_set_variable_int(L"BootCurrent",
|
|
|
&efi_global_variable_guid,
|
|
|
- attributes, size, &n, false);
|
|
|
+ attributes, sizeof(n), &n, false);
|
|
|
if (ret != EFI_SUCCESS) {
|
|
|
if (EFI_CALL(efi_unload_image(*handle))
|
|
|
!= EFI_SUCCESS)
|
|
@@ -266,6 +267,19 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle)
|
|
|
ret = EFI_LOAD_ERROR;
|
|
|
}
|
|
|
|
|
|
+ /* Set load options */
|
|
|
+ if (size) {
|
|
|
+ *load_options = malloc(size);
|
|
|
+ if (!*load_options) {
|
|
|
+ ret = EFI_OUT_OF_RESOURCES;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ memcpy(*load_options, lo.optional_data, size);
|
|
|
+ ret = efi_set_load_options(*handle, size, *load_options);
|
|
|
+ } else {
|
|
|
+ load_options = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
error:
|
|
|
free(load_option);
|
|
|
|
|
@@ -279,10 +293,11 @@ error:
|
|
|
* EFI variable, the available load-options, finding and returning
|
|
|
* the first one that can be loaded successfully.
|
|
|
*
|
|
|
- * @handle: on return handle for the newly installed image
|
|
|
- * Return: status code
|
|
|
+ * @handle: on return handle for the newly installed image
|
|
|
+ * @load_options: load options set on the loaded image protocol
|
|
|
+ * Return: status code
|
|
|
*/
|
|
|
-efi_status_t efi_bootmgr_load(efi_handle_t *handle)
|
|
|
+efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options)
|
|
|
{
|
|
|
u16 bootnext, *bootorder;
|
|
|
efi_uintn_t size;
|
|
@@ -310,7 +325,8 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle)
|
|
|
/* load BootNext */
|
|
|
if (ret == EFI_SUCCESS) {
|
|
|
if (size == sizeof(u16)) {
|
|
|
- ret = try_load_entry(bootnext, handle);
|
|
|
+ ret = try_load_entry(bootnext, handle,
|
|
|
+ load_options);
|
|
|
if (ret == EFI_SUCCESS)
|
|
|
return ret;
|
|
|
log_warning(
|
|
@@ -333,7 +349,7 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle)
|
|
|
for (i = 0; i < num; i++) {
|
|
|
log_debug("%s trying to load Boot%04X\n", __func__,
|
|
|
bootorder[i]);
|
|
|
- ret = try_load_entry(bootorder[i], handle);
|
|
|
+ ret = try_load_entry(bootorder[i], handle, load_options);
|
|
|
if (ret == EFI_SUCCESS)
|
|
|
break;
|
|
|
}
|