mirror of
https://github.com/systemd/systemd.git
synced 2024-10-27 01:55:22 +03:00
Merge pull request #33574 from poettering/get-efi-var-raw
efi: efi variable refactoring
This commit is contained in:
commit
6f5c8f44f1
@ -7,6 +7,7 @@
|
||||
#include "devicetree.h"
|
||||
#include "drivers.h"
|
||||
#include "efivars-fundamental.h"
|
||||
#include "efivars.h"
|
||||
#include "export-vars.h"
|
||||
#include "graphics.h"
|
||||
#include "initrd.h"
|
||||
@ -490,7 +491,7 @@ static void print_status(Config *config, char16_t *loaded_image_path) {
|
||||
query_screen_resolution(&screen_width, &screen_height);
|
||||
|
||||
secure = secure_boot_mode();
|
||||
(void) efivar_get(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", &device_part_uuid);
|
||||
(void) efivar_get_str16(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", &device_part_uuid);
|
||||
|
||||
printf(" systemd-boot version: " GIT_VERSION "\n");
|
||||
if (loaded_image_path)
|
||||
@ -1104,14 +1105,14 @@ static bool menu_run(
|
||||
/* Update EFI vars after we left the menu to reduce NVRAM writes. */
|
||||
|
||||
if (default_efivar_saved != config->idx_default_efivar)
|
||||
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderEntryDefault", config->entry_default_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderEntryDefault", config->entry_default_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||
|
||||
if (console_mode_efivar_saved != config->console_mode_efivar) {
|
||||
if (config->console_mode_efivar == CONSOLE_MODE_KEEP)
|
||||
efivar_unset(MAKE_GUID_PTR(LOADER), u"LoaderConfigConsoleMode", EFI_VARIABLE_NON_VOLATILE);
|
||||
else
|
||||
efivar_set_uint_string(MAKE_GUID_PTR(LOADER), u"LoaderConfigConsoleMode",
|
||||
config->console_mode_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||
efivar_set_uint64_str16(MAKE_GUID_PTR(LOADER), u"LoaderConfigConsoleMode",
|
||||
config->console_mode_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||
}
|
||||
|
||||
if (timeout_efivar_saved != config->timeout_sec_efivar) {
|
||||
@ -1122,15 +1123,15 @@ static bool menu_run(
|
||||
case TIMEOUT_MENU_DISABLED:
|
||||
assert_not_reached();
|
||||
case TIMEOUT_MENU_FORCE:
|
||||
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderConfigTimeout", u"menu-force", EFI_VARIABLE_NON_VOLATILE);
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderConfigTimeout", u"menu-force", EFI_VARIABLE_NON_VOLATILE);
|
||||
break;
|
||||
case TIMEOUT_MENU_HIDDEN:
|
||||
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderConfigTimeout", u"menu-hidden", EFI_VARIABLE_NON_VOLATILE);
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderConfigTimeout", u"menu-hidden", EFI_VARIABLE_NON_VOLATILE);
|
||||
break;
|
||||
default:
|
||||
assert(config->timeout_sec_efivar < UINT32_MAX);
|
||||
efivar_set_uint_string(MAKE_GUID_PTR(LOADER), u"LoaderConfigTimeout",
|
||||
config->timeout_sec_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||
efivar_set_uint64_str16(MAKE_GUID_PTR(LOADER), u"LoaderConfigTimeout",
|
||||
config->timeout_sec_efivar, EFI_VARIABLE_NON_VOLATILE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1396,7 +1397,7 @@ static EFI_STATUS boot_entry_bump_counters(BootEntry *entry) {
|
||||
/* Let's tell the OS that we renamed this file, so that it knows what to rename to the counter-less name on
|
||||
* success */
|
||||
new_path = xasprintf("%ls\\%ls", entry->path, entry->next_name);
|
||||
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderBootCountPath", new_path, 0);
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderBootCountPath", new_path, 0);
|
||||
|
||||
/* If the file we just renamed is the loader path, then let's update that. */
|
||||
if (streq16(entry->loader, old_path)) {
|
||||
@ -1526,7 +1527,7 @@ static EFI_STATUS efivar_get_timeout(const char16_t *var, uint64_t *ret_value) {
|
||||
assert(var);
|
||||
assert(ret_value);
|
||||
|
||||
err = efivar_get(MAKE_GUID_PTR(LOADER), var, &value);
|
||||
err = efivar_get_str16(MAKE_GUID_PTR(LOADER), var, &value);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
@ -1553,7 +1554,7 @@ static EFI_STATUS efivar_get_timeout(const char16_t *var, uint64_t *ret_value) {
|
||||
|
||||
static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
||||
_cleanup_free_ char *content = NULL;
|
||||
size_t content_size, value = 0; /* avoid false maybe-uninitialized warning */
|
||||
size_t content_size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(root_dir);
|
||||
@ -1602,16 +1603,17 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
||||
} else if (err != EFI_NOT_FOUND)
|
||||
log_error_status(err, "Error reading LoaderConfigTimeoutOneShot EFI variable: %m");
|
||||
|
||||
err = efivar_get_uint_string(MAKE_GUID_PTR(LOADER), u"LoaderConfigConsoleMode", &value);
|
||||
if (err == EFI_SUCCESS)
|
||||
uint64_t value;
|
||||
err = efivar_get_uint64_str16(MAKE_GUID_PTR(LOADER), u"LoaderConfigConsoleMode", &value);
|
||||
if (err == EFI_SUCCESS && value <= INT64_MAX)
|
||||
config->console_mode_efivar = value;
|
||||
|
||||
err = efivar_get(MAKE_GUID_PTR(LOADER), u"LoaderEntryOneShot", &config->entry_oneshot);
|
||||
err = efivar_get_str16(MAKE_GUID_PTR(LOADER), u"LoaderEntryOneShot", &config->entry_oneshot);
|
||||
if (err == EFI_SUCCESS)
|
||||
/* Unset variable now, after all it's "one shot". */
|
||||
(void) efivar_unset(MAKE_GUID_PTR(LOADER), u"LoaderEntryOneShot", EFI_VARIABLE_NON_VOLATILE);
|
||||
|
||||
(void) efivar_get(MAKE_GUID_PTR(LOADER), u"LoaderEntryDefault", &config->entry_default_efivar);
|
||||
(void) efivar_get_str16(MAKE_GUID_PTR(LOADER), u"LoaderEntryDefault", &config->entry_default_efivar);
|
||||
|
||||
strtolower16(config->entry_default_config);
|
||||
strtolower16(config->entry_default_efivar);
|
||||
@ -1621,7 +1623,7 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
||||
config->use_saved_entry = streq16(config->entry_default_config, u"@saved");
|
||||
config->use_saved_entry_efivar = streq16(config->entry_default_efivar, u"@saved");
|
||||
if (config->use_saved_entry || config->use_saved_entry_efivar)
|
||||
(void) efivar_get(MAKE_GUID_PTR(LOADER), u"LoaderEntryLastBooted", &config->entry_saved);
|
||||
(void) efivar_get_str16(MAKE_GUID_PTR(LOADER), u"LoaderEntryLastBooted", &config->entry_saved);
|
||||
}
|
||||
|
||||
static void config_load_type1_entries(
|
||||
@ -2014,7 +2016,7 @@ static EFI_STATUS boot_windows_bitlocker(void) {
|
||||
|
||||
/* There can be gaps in Boot#### entries. Instead of iterating over the full
|
||||
* EFI var list or uint16_t namespace, just look for "Windows Boot Manager" in BootOrder. */
|
||||
err = efivar_get_raw(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"BootOrder", (char **) &boot_order, &boot_order_size);
|
||||
err = efivar_get_raw(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"BootOrder", (void**) &boot_order, &boot_order_size);
|
||||
if (err != EFI_SUCCESS || boot_order_size % sizeof(uint16_t) != 0)
|
||||
return err;
|
||||
|
||||
@ -2023,7 +2025,7 @@ static EFI_STATUS boot_windows_bitlocker(void) {
|
||||
size_t buf_size;
|
||||
|
||||
_cleanup_free_ char16_t *name = xasprintf("Boot%04x", boot_order[i]);
|
||||
err = efivar_get_raw(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), name, &buf, &buf_size);
|
||||
err = efivar_get_raw(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), name, (void**) &buf, &buf_size);
|
||||
if (err != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
@ -2472,7 +2474,7 @@ static void save_selected_entry(const Config *config, const BootEntry *entry) {
|
||||
assert(entry->loader || !entry->call);
|
||||
|
||||
/* Always export the selected boot entry to the system in a volatile var. */
|
||||
(void) efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderEntrySelected", entry->id, 0);
|
||||
(void) efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderEntrySelected", entry->id, 0);
|
||||
|
||||
/* Do not save or delete if this was a oneshot boot. */
|
||||
if (streq16(config->entry_oneshot, entry->id))
|
||||
@ -2483,7 +2485,7 @@ static void save_selected_entry(const Config *config, const BootEntry *entry) {
|
||||
if (streq16(config->entry_saved, entry->id))
|
||||
return;
|
||||
|
||||
(void) efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderEntryLastBooted", entry->id, EFI_VARIABLE_NON_VOLATILE);
|
||||
(void) efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderEntryLastBooted", entry->id, EFI_VARIABLE_NON_VOLATILE);
|
||||
} else
|
||||
/* Delete the non-volatile var if not needed. */
|
||||
(void) efivar_unset(MAKE_GUID_PTR(LOADER), u"LoaderEntryLastBooted", EFI_VARIABLE_NON_VOLATILE);
|
||||
@ -2563,7 +2565,7 @@ static void export_loader_variables(
|
||||
assert(loaded_image);
|
||||
|
||||
(void) efivar_set_time_usec(MAKE_GUID_PTR(LOADER), u"LoaderTimeInitUSec", init_usec);
|
||||
(void) efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderInfo", u"systemd-boot " GIT_VERSION, 0);
|
||||
(void) efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderInfo", u"systemd-boot " GIT_VERSION, 0);
|
||||
(void) efivar_set_uint64_le(MAKE_GUID_PTR(LOADER), u"LoaderFeatures", loader_features, 0);
|
||||
}
|
||||
|
||||
|
247
src/boot/efi/efivars.c
Normal file
247
src/boot/efi/efivars.c
Normal file
@ -0,0 +1,247 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "efi-string.h"
|
||||
#include "efivars.h"
|
||||
#include "ticks.h"
|
||||
#include "util.h"
|
||||
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
assert(buf || size == 0);
|
||||
|
||||
flags |= EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
return RT->SetVariable((char16_t *) name, (EFI_GUID *) vendor, flags, size, (void *) buf);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_str16(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
return efivar_set_raw(vendor, name, value, value ? strsize16(value) : 0, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint64_str16(const EFI_GUID *vendor, const char16_t *name, uint64_t i, uint32_t flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
_cleanup_free_ char16_t *str = xasprintf("%" PRIu64, i);
|
||||
return efivar_set_str16(vendor, name, str, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags) {
|
||||
uint8_t buf[4];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
buf[0] = (uint8_t)(value >> 0U & 0xFF);
|
||||
buf[1] = (uint8_t)(value >> 8U & 0xFF);
|
||||
buf[2] = (uint8_t)(value >> 16U & 0xFF);
|
||||
buf[3] = (uint8_t)(value >> 24U & 0xFF);
|
||||
|
||||
return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags) {
|
||||
uint8_t buf[8];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
buf[0] = (uint8_t)(value >> 0U & 0xFF);
|
||||
buf[1] = (uint8_t)(value >> 8U & 0xFF);
|
||||
buf[2] = (uint8_t)(value >> 16U & 0xFF);
|
||||
buf[3] = (uint8_t)(value >> 24U & 0xFF);
|
||||
buf[4] = (uint8_t)(value >> 32U & 0xFF);
|
||||
buf[5] = (uint8_t)(value >> 40U & 0xFF);
|
||||
buf[6] = (uint8_t)(value >> 48U & 0xFF);
|
||||
buf[7] = (uint8_t)(value >> 56U & 0xFF);
|
||||
|
||||
return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_unset(const EFI_GUID *vendor, const char16_t *name, uint32_t flags) {
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
/* We could be wiping a non-volatile variable here and the spec makes no guarantees that won't incur
|
||||
* in an extra write (and thus wear out). So check and clear only if needed. */
|
||||
err = efivar_get_raw(vendor, name, NULL, NULL);
|
||||
if (err == EFI_SUCCESS)
|
||||
return efivar_set_raw(vendor, name, NULL, 0, flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_str16(const EFI_GUID *vendor, const char16_t *name, char16_t **ret) {
|
||||
_cleanup_free_ char16_t *buf = NULL;
|
||||
EFI_STATUS err;
|
||||
char16_t *val;
|
||||
size_t size;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, (void**) &buf, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Make sure there are no incomplete characters in the buffer */
|
||||
if ((size % sizeof(char16_t)) != 0)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (!ret)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
/* Return buffer directly if it happens to be NUL terminated already */
|
||||
if (size >= sizeof(char16_t) && buf[size / sizeof(char16_t) - 1] == 0) {
|
||||
*ret = TAKE_PTR(buf);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make sure a terminating NUL is available at the end */
|
||||
val = xmalloc(size + sizeof(char16_t));
|
||||
|
||||
memcpy(val, buf, size);
|
||||
val[size / sizeof(char16_t) - 1] = 0; /* NUL terminate */
|
||||
|
||||
*ret = val;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint64_str16(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret) {
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
_cleanup_free_ char16_t *val = NULL;
|
||||
err = efivar_get_str16(vendor, name, &val);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
uint64_t u;
|
||||
if (!parse_number16(val, &u, NULL))
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (ret)
|
||||
*ret = u;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret) {
|
||||
_cleanup_free_ uint8_t *buf = NULL;
|
||||
size_t size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, (void**) &buf, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (size != sizeof(uint32_t))
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
|
||||
if (ret)
|
||||
*ret = (uint32_t) buf[0] << 0U | (uint32_t) buf[1] << 8U | (uint32_t) buf[2] << 16U |
|
||||
(uint32_t) buf[3] << 24U;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret) {
|
||||
_cleanup_free_ uint8_t *buf = NULL;
|
||||
size_t size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, (void**) &buf, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (size != sizeof(uint64_t))
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
|
||||
if (ret)
|
||||
*ret = (uint64_t) buf[0] << 0U | (uint64_t) buf[1] << 8U | (uint64_t) buf[2] << 16U |
|
||||
(uint64_t) buf[3] << 24U | (uint64_t) buf[4] << 32U | (uint64_t) buf[5] << 40U |
|
||||
(uint64_t) buf[6] << 48U | (uint64_t) buf[7] << 56U;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, void **ret, size_t *ret_size) {
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
size_t size = 0;
|
||||
err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, NULL);
|
||||
if (err != EFI_BUFFER_TOO_SMALL)
|
||||
return err;
|
||||
|
||||
_cleanup_free_ void *buf = xmalloc(size);
|
||||
err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, buf);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(buf);
|
||||
if (ret_size)
|
||||
*ret_size = size;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret) {
|
||||
_cleanup_free_ uint8_t *b = NULL;
|
||||
size_t size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, (void**) &b, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (ret)
|
||||
*ret = *b > 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
if (usec == 0)
|
||||
usec = time_usec();
|
||||
if (usec == 0)
|
||||
return;
|
||||
|
||||
_cleanup_free_ char16_t *str = xasprintf("%" PRIu64, usec);
|
||||
efivar_set_str16(vendor, name, str, 0);
|
||||
}
|
||||
|
||||
uint64_t get_os_indications_supported(void) {
|
||||
uint64_t osind;
|
||||
EFI_STATUS err;
|
||||
|
||||
/* Returns the supported OS indications. If we can't acquire it, returns a zeroed out mask, i.e. no
|
||||
* supported features. */
|
||||
|
||||
err = efivar_get_uint64_le(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"OsIndicationsSupported", &osind);
|
||||
if (err != EFI_SUCCESS)
|
||||
return 0;
|
||||
|
||||
return osind;
|
||||
}
|
30
src/boot/efi/efivars.h
Normal file
30
src/boot/efi/efivars.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "efi.h"
|
||||
|
||||
/*
|
||||
* Allocated random UUID, intended to be shared across tools that implement
|
||||
* the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
|
||||
* associated EFI variables.
|
||||
*/
|
||||
#define LOADER_GUID \
|
||||
{ 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
|
||||
|
||||
EFI_STATUS efivar_set_str16(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags);
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint64_str16(const EFI_GUID *vendor, const char16_t *name, uint64_t i, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags);
|
||||
void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec);
|
||||
|
||||
EFI_STATUS efivar_unset(const EFI_GUID *vendor, const char16_t *name, uint32_t flags);
|
||||
|
||||
EFI_STATUS efivar_get_str16(const EFI_GUID *vendor, const char16_t *name, char16_t **ret);
|
||||
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, void **ret, size_t *ret_size);
|
||||
EFI_STATUS efivar_get_uint64_str16(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret);
|
||||
EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret);
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret);
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret);
|
||||
|
||||
uint64_t get_os_indications_supported(void);
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "device-path-util.h"
|
||||
#include "efivars.h"
|
||||
#include "export-vars.h"
|
||||
#include "part-discovery.h"
|
||||
#include "util.h"
|
||||
@ -12,7 +13,7 @@ void export_common_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) {
|
||||
if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS) {
|
||||
_cleanup_free_ char16_t *uuid = disk_get_part_uuid(loaded_image->DeviceHandle);
|
||||
if (uuid)
|
||||
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", uuid, 0);
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", uuid, 0);
|
||||
}
|
||||
|
||||
/* If LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from the
|
||||
@ -25,20 +26,20 @@ void export_common_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) {
|
||||
loaded_image->FilePath) {
|
||||
_cleanup_free_ char16_t *s = NULL;
|
||||
if (device_path_to_str(loaded_image->FilePath, &s) == EFI_SUCCESS)
|
||||
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", s, 0);
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", s, 0);
|
||||
}
|
||||
|
||||
/* if LoaderFirmwareInfo is not set, let's set it */
|
||||
if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) {
|
||||
_cleanup_free_ char16_t *s = NULL;
|
||||
s = xasprintf("%ls %u.%02u", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
|
||||
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareInfo", s, 0);
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareInfo", s, 0);
|
||||
}
|
||||
|
||||
/* ditto for LoaderFirmwareType */
|
||||
if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) {
|
||||
_cleanup_free_ char16_t *s = NULL;
|
||||
s = xasprintf("UEFI %u.%02u", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
|
||||
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareType", s, 0);
|
||||
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderFirmwareType", s, 0);
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +258,7 @@ libefi_sources = files(
|
||||
'devicetree.c',
|
||||
'drivers.c',
|
||||
'efi-string.c',
|
||||
'efivars.c',
|
||||
'export-vars.c',
|
||||
'graphics.c',
|
||||
'initrd.c',
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "efivars.h"
|
||||
#include "memory-util-fundamental.h"
|
||||
#include "proto/rng.h"
|
||||
#include "random-seed.h"
|
||||
@ -55,7 +56,7 @@ static EFI_STATUS acquire_system_token(void **ret, size_t *ret_size) {
|
||||
assert(ret);
|
||||
assert(ret_size);
|
||||
|
||||
err = efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderSystemToken", &data, &size);
|
||||
err = efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderSystemToken", (void**) &data, &size);
|
||||
if (err != EFI_SUCCESS) {
|
||||
if (err != EFI_NOT_FOUND)
|
||||
log_error_status(err, "Failed to read LoaderSystemToken EFI variable: %m");
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "console.h"
|
||||
#include "efivars.h"
|
||||
#include "proto/security-arch.h"
|
||||
#include "secure-boot.h"
|
||||
#include "util.h"
|
||||
|
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "device-path-util.h"
|
||||
#include "efivars.h"
|
||||
#include "secure-boot.h"
|
||||
#include "shim.h"
|
||||
#include "util.h"
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "cpio.h"
|
||||
#include "device-path-util.h"
|
||||
#include "devicetree.h"
|
||||
#include "efivars.h"
|
||||
#include "export-vars.h"
|
||||
#include "graphics.h"
|
||||
#include "iovec-util-fundamental.h"
|
||||
@ -156,7 +157,7 @@ static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) {
|
||||
|
||||
/* add StubInfo (this is one is owned by the stub, hence we unconditionally override this with our
|
||||
* own data) */
|
||||
(void) efivar_set(MAKE_GUID_PTR(LOADER), u"StubInfo", u"systemd-stub " GIT_VERSION, 0);
|
||||
(void) efivar_set_str16(MAKE_GUID_PTR(LOADER), u"StubInfo", u"systemd-stub " GIT_VERSION, 0);
|
||||
|
||||
(void) efivar_set_uint64_le(MAKE_GUID_PTR(LOADER), u"StubFeatures", stub_features, 0);
|
||||
}
|
||||
@ -745,13 +746,13 @@ static void export_pcr_variables(
|
||||
* successfully, and encode in it which PCR was used. */
|
||||
|
||||
if (sections_measured > 0)
|
||||
(void) efivar_set_uint_string(MAKE_GUID_PTR(LOADER), u"StubPcrKernelImage", TPM2_PCR_KERNEL_BOOT, 0);
|
||||
(void) efivar_set_uint64_str16(MAKE_GUID_PTR(LOADER), u"StubPcrKernelImage", TPM2_PCR_KERNEL_BOOT, 0);
|
||||
if (parameters_measured > 0)
|
||||
(void) efivar_set_uint_string(MAKE_GUID_PTR(LOADER), u"StubPcrKernelParameters", TPM2_PCR_KERNEL_CONFIG, 0);
|
||||
(void) efivar_set_uint64_str16(MAKE_GUID_PTR(LOADER), u"StubPcrKernelParameters", TPM2_PCR_KERNEL_CONFIG, 0);
|
||||
if (sysext_measured > 0)
|
||||
(void) efivar_set_uint_string(MAKE_GUID_PTR(LOADER), u"StubPcrInitRDSysExts", TPM2_PCR_SYSEXTS, 0);
|
||||
(void) efivar_set_uint64_str16(MAKE_GUID_PTR(LOADER), u"StubPcrInitRDSysExts", TPM2_PCR_SYSEXTS, 0);
|
||||
if (confext_measured > 0)
|
||||
(void) efivar_set_uint_string(MAKE_GUID_PTR(LOADER), u"StubPcrInitRDConfExts", TPM2_PCR_KERNEL_CONFIG, 0);
|
||||
(void) efivar_set_uint64_str16(MAKE_GUID_PTR(LOADER), u"StubPcrInitRDConfExts", TPM2_PCR_KERNEL_CONFIG, 0);
|
||||
}
|
||||
|
||||
static void install_embedded_devicetree(
|
||||
|
@ -7,233 +7,7 @@
|
||||
#include "ticks.h"
|
||||
#include "util.h"
|
||||
#include "version.h"
|
||||
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
assert(buf || size == 0);
|
||||
|
||||
flags |= EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
return RT->SetVariable((char16_t *) name, (EFI_GUID *) vendor, flags, size, (void *) buf);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
return efivar_set_raw(vendor, name, value, value ? strsize16(value) : 0, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t i, uint32_t flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
_cleanup_free_ char16_t *str = xasprintf("%zu", i);
|
||||
return efivar_set(vendor, name, str, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags) {
|
||||
uint8_t buf[4];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
buf[0] = (uint8_t)(value >> 0U & 0xFF);
|
||||
buf[1] = (uint8_t)(value >> 8U & 0xFF);
|
||||
buf[2] = (uint8_t)(value >> 16U & 0xFF);
|
||||
buf[3] = (uint8_t)(value >> 24U & 0xFF);
|
||||
|
||||
return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags) {
|
||||
uint8_t buf[8];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
buf[0] = (uint8_t)(value >> 0U & 0xFF);
|
||||
buf[1] = (uint8_t)(value >> 8U & 0xFF);
|
||||
buf[2] = (uint8_t)(value >> 16U & 0xFF);
|
||||
buf[3] = (uint8_t)(value >> 24U & 0xFF);
|
||||
buf[4] = (uint8_t)(value >> 32U & 0xFF);
|
||||
buf[5] = (uint8_t)(value >> 40U & 0xFF);
|
||||
buf[6] = (uint8_t)(value >> 48U & 0xFF);
|
||||
buf[7] = (uint8_t)(value >> 56U & 0xFF);
|
||||
|
||||
return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_unset(const EFI_GUID *vendor, const char16_t *name, uint32_t flags) {
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
/* We could be wiping a non-volatile variable here and the spec makes no guarantees that won't incur
|
||||
* in an extra write (and thus wear out). So check and clear only if needed. */
|
||||
err = efivar_get_raw(vendor, name, NULL, NULL);
|
||||
if (err == EFI_SUCCESS)
|
||||
return efivar_set_raw(vendor, name, NULL, 0, flags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **ret) {
|
||||
_cleanup_free_ char16_t *buf = NULL;
|
||||
EFI_STATUS err;
|
||||
char16_t *val;
|
||||
size_t size;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, (char **) &buf, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Make sure there are no incomplete characters in the buffer */
|
||||
if ((size % sizeof(char16_t)) != 0)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (!ret)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
/* Return buffer directly if it happens to be NUL terminated already */
|
||||
if (size >= sizeof(char16_t) && buf[size / sizeof(char16_t) - 1] == 0) {
|
||||
*ret = TAKE_PTR(buf);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make sure a terminating NUL is available at the end */
|
||||
val = xmalloc(size + sizeof(char16_t));
|
||||
|
||||
memcpy(val, buf, size);
|
||||
val[size / sizeof(char16_t) - 1] = 0; /* NUL terminate */
|
||||
|
||||
*ret = val;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t *ret) {
|
||||
_cleanup_free_ char16_t *val = NULL;
|
||||
EFI_STATUS err;
|
||||
uint64_t u;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get(vendor, name, &val);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (!parse_number16(val, &u, NULL) || u > SIZE_MAX)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (ret)
|
||||
*ret = u;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
size_t size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &buf, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (size != sizeof(uint32_t))
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
|
||||
if (ret)
|
||||
*ret = (uint32_t) buf[0] << 0U | (uint32_t) buf[1] << 8U | (uint32_t) buf[2] << 16U |
|
||||
(uint32_t) buf[3] << 24U;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
size_t size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &buf, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (size != sizeof(uint64_t))
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
|
||||
if (ret)
|
||||
*ret = (uint64_t) buf[0] << 0U | (uint64_t) buf[1] << 8U | (uint64_t) buf[2] << 16U |
|
||||
(uint64_t) buf[3] << 24U | (uint64_t) buf[4] << 32U | (uint64_t) buf[5] << 40U |
|
||||
(uint64_t) buf[6] << 48U | (uint64_t) buf[7] << 56U;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **ret, size_t *ret_size) {
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
size_t size = 0;
|
||||
err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, NULL);
|
||||
if (err != EFI_BUFFER_TOO_SMALL)
|
||||
return err;
|
||||
|
||||
_cleanup_free_ void *buf = xmalloc(size);
|
||||
err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &size, buf);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(buf);
|
||||
if (ret_size)
|
||||
*ret_size = size;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
size_t size;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &b, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (ret)
|
||||
*ret = *b > 0;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
if (usec == 0)
|
||||
usec = time_usec();
|
||||
if (usec == 0)
|
||||
return;
|
||||
|
||||
_cleanup_free_ char16_t *str = xasprintf("%" PRIu64, usec);
|
||||
efivar_set(vendor, name, str, 0);
|
||||
}
|
||||
#include "efivars.h"
|
||||
|
||||
void convert_efi_path(char16_t *path) {
|
||||
assert(path);
|
||||
@ -544,20 +318,6 @@ EFI_STATUS open_directory(
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
uint64_t get_os_indications_supported(void) {
|
||||
uint64_t osind;
|
||||
EFI_STATUS err;
|
||||
|
||||
/* Returns the supported OS indications. If we can't acquire it, returns a zeroed out mask, i.e. no
|
||||
* supported features. */
|
||||
|
||||
err = efivar_get_uint64_le(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"OsIndicationsSupported", &osind);
|
||||
if (err != EFI_SUCCESS)
|
||||
return 0;
|
||||
|
||||
return osind;
|
||||
}
|
||||
|
||||
__attribute__((noinline)) void notify_debugger(const char *identity, volatile bool wait) {
|
||||
#ifdef EFI_DEBUG
|
||||
printf("%s@%p %s\n", identity, __executable_start, GIT_VERSION);
|
||||
|
@ -81,22 +81,6 @@ static inline Pages xmalloc_pages(
|
||||
};
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags);
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, size_t size, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t i, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags);
|
||||
void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec);
|
||||
|
||||
EFI_STATUS efivar_unset(const EFI_GUID *vendor, const char16_t *name, uint32_t flags);
|
||||
|
||||
EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **ret);
|
||||
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **ret, size_t *ret_size);
|
||||
EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, size_t *ret);
|
||||
EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret);
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret);
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret);
|
||||
|
||||
void convert_efi_path(char16_t *path);
|
||||
char16_t *xstr8_to_path(const char *stra);
|
||||
char16_t *mangle_stub_cmdline(char16_t *cmdline);
|
||||
@ -116,14 +100,6 @@ static inline void unload_imagep(EFI_HANDLE *image) {
|
||||
(void) BS->UnloadImage(*image);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocated random UUID, intended to be shared across tools that implement
|
||||
* the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
|
||||
* associated EFI variables.
|
||||
*/
|
||||
#define LOADER_GUID \
|
||||
{ 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
|
||||
|
||||
/* Note that GUID is evaluated multiple times! */
|
||||
#define GUID_FORMAT_STR "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
|
||||
#define GUID_FORMAT_VAL(g) (g).Data1, (g).Data2, (g).Data3, (g).Data4[0], (g).Data4[1], \
|
||||
@ -162,8 +138,6 @@ static inline void *PHYSICAL_ADDRESS_TO_POINTER(EFI_PHYSICAL_ADDRESS addr) {
|
||||
return (void *) (uintptr_t) addr;
|
||||
}
|
||||
|
||||
uint64_t get_os_indications_supported(void);
|
||||
|
||||
/* If EFI_DEBUG, print our name and version and also report the address of the image base so a debugger can
|
||||
* be attached. See debug-sd-boot.sh for how this can be done. */
|
||||
void notify_debugger(const char *identity, bool wait);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "device-path-util.h"
|
||||
#include "drivers.h"
|
||||
#include "efi-string.h"
|
||||
#include "efivars.h"
|
||||
#include "proto/device-path.h"
|
||||
#include "string-util-fundamental.h"
|
||||
#include "util.h"
|
||||
@ -80,7 +81,7 @@ EFI_STATUS vmm_open(EFI_HANDLE *ret_vmm_dev, EFI_FILE **ret_vmm_dir) {
|
||||
_cleanup_free_ EFI_DEVICE_PATH *dp = NULL;
|
||||
|
||||
_cleanup_free_ char16_t *order_str = xasprintf("VMMBootOrder%04zx", order);
|
||||
dp_err = efivar_get_raw(MAKE_GUID_PTR(VMM_BOOT_ORDER), order_str, (char **) &dp, NULL);
|
||||
dp_err = efivar_get_raw(MAKE_GUID_PTR(VMM_BOOT_ORDER), order_str, (void**) &dp, NULL);
|
||||
|
||||
for (size_t i = 0; i < n_handles; i++) {
|
||||
_cleanup_(file_closep) EFI_FILE *root_dir = NULL, *efi_dir = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user