mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-04-02 12:31:31 +00:00
efi_loader: bootmgr: support BootNext and BootCurrent variable behavior
See UEFI v2.7, section 3.1.2 for details of the specification. With efidebug command, you can run any EFI boot option as follows: => efi boot add 1 SHELL ... => efi boot add 2 HELLO ... => efi boot order 1 2 => efi bootmgr (starting SHELL ...) => efi boot next 2 => efi bootmgr (starting HELLO ...) => env print -e <snip ...> BootCurrent: {boot,run}(blob) 00000000: 02 00 .. BootOrder: {boot,run}(blob) 00000000: 01 00 02 00 .... Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
b0c3c346c6
commit
37279ad3ee
1 changed files with 47 additions and 4 deletions
|
@ -141,6 +141,7 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
|
||||||
efi_deserialize_load_option(&lo, load_option);
|
efi_deserialize_load_option(&lo, load_option);
|
||||||
|
|
||||||
if (lo.attributes & LOAD_OPTION_ACTIVE) {
|
if (lo.attributes & LOAD_OPTION_ACTIVE) {
|
||||||
|
u32 attributes;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
|
||||||
debug("%s: trying to load \"%ls\" from %pD\n",
|
debug("%s: trying to load \"%ls\" from %pD\n",
|
||||||
|
@ -151,6 +152,16 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
|
EFI_VARIABLE_RUNTIME_ACCESS;
|
||||||
|
size = sizeof(n);
|
||||||
|
ret = EFI_CALL(efi_set_variable(
|
||||||
|
L"BootCurrent",
|
||||||
|
(efi_guid_t *)&efi_global_variable_guid,
|
||||||
|
attributes, size, &n));
|
||||||
|
if (ret != EFI_SUCCESS)
|
||||||
|
goto error;
|
||||||
|
|
||||||
printf("Booting: %ls\n", lo.label);
|
printf("Booting: %ls\n", lo.label);
|
||||||
efi_dp_split_file_path(lo.file_path, device_path, file_path);
|
efi_dp_split_file_path(lo.file_path, device_path, file_path);
|
||||||
}
|
}
|
||||||
|
@ -162,21 +173,53 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attempt to load, in the order specified by BootOrder EFI variable, the
|
* Attempt to load from BootNext or in the order specified by BootOrder
|
||||||
* available load-options, finding and returning the first one that can
|
* EFI variable, the available load-options, finding and returning
|
||||||
* be loaded successfully.
|
* the first one that can be loaded successfully.
|
||||||
*/
|
*/
|
||||||
void *efi_bootmgr_load(struct efi_device_path **device_path,
|
void *efi_bootmgr_load(struct efi_device_path **device_path,
|
||||||
struct efi_device_path **file_path)
|
struct efi_device_path **file_path)
|
||||||
{
|
{
|
||||||
uint16_t *bootorder;
|
u16 bootnext, *bootorder;
|
||||||
efi_uintn_t size;
|
efi_uintn_t size;
|
||||||
void *image = NULL;
|
void *image = NULL;
|
||||||
int i, num;
|
int i, num;
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
bs = systab.boottime;
|
bs = systab.boottime;
|
||||||
rs = systab.runtime;
|
rs = systab.runtime;
|
||||||
|
|
||||||
|
/* BootNext */
|
||||||
|
bootnext = 0;
|
||||||
|
size = sizeof(bootnext);
|
||||||
|
ret = EFI_CALL(efi_get_variable(L"BootNext",
|
||||||
|
(efi_guid_t *)&efi_global_variable_guid,
|
||||||
|
NULL, &size, &bootnext));
|
||||||
|
if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
|
||||||
|
/* BootNext does exist here */
|
||||||
|
if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16))
|
||||||
|
printf("BootNext must be 16-bit integer\n");
|
||||||
|
|
||||||
|
/* delete BootNext */
|
||||||
|
ret = EFI_CALL(efi_set_variable(
|
||||||
|
L"BootNext",
|
||||||
|
(efi_guid_t *)&efi_global_variable_guid,
|
||||||
|
0, 0, &bootnext));
|
||||||
|
|
||||||
|
/* load BootNext */
|
||||||
|
if (ret == EFI_SUCCESS) {
|
||||||
|
if (size == sizeof(u16)) {
|
||||||
|
image = try_load_entry(bootnext, device_path,
|
||||||
|
file_path);
|
||||||
|
if (image)
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("Deleting BootNext failed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BootOrder */
|
||||||
bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size);
|
bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size);
|
||||||
if (!bootorder) {
|
if (!bootorder) {
|
||||||
printf("BootOrder not defined\n");
|
printf("BootOrder not defined\n");
|
||||||
|
|
Loading…
Add table
Reference in a new issue