generally only written once, by the OS installer, and is usually not touched
after that.
+* The EFI variable `LoaderDeviceURL` contains the URL the boot loader was
+ downloaded from, in UTF-16 format. Only set in case of network boots.
+
If `LoaderTimeInitUSec` and `LoaderTimeExecUSec` are set, `systemd-analyze`
will include them in its boot-time analysis. If `LoaderDevicePartUUID` is set,
systemd will mount the ESP that was used for the boot to `/boot`, but only if
<xi:include href="version-info.xml" xpointer="v220"/></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>LoaderDeviceURL</varname></term>
+
+ <listitem><para>If the boot loader has been invoked via network booting this variable contains the
+ originating URL. This may be used to automatically acquire additional resources from the same
+ source.</para>
+
+ <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>LoaderEntries</varname></term>
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>StubDeviceURL</varname></term>
+
+ <listitem><para>If the kernel image has been invoked via network booting this variable contains the
+ originating URL. This may be used to automatically acquire additional resources from the same
+ source.</para>
+
+ <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>StubInfo</varname></term>
EFI_LOADER_FEATURE_RETAIN_SHIM |
EFI_LOADER_FEATURE_MENU_DISABLE |
EFI_LOADER_FEATURE_MULTI_PROFILE_UKI |
+ EFI_LOADER_FEATURE_REPORT_URL |
0;
assert(loaded_image);
#include "efivars.h"
#include "export-vars.h"
#include "part-discovery.h"
+#include "url-discovery.h"
#include "util.h"
void export_common_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) {
assert(loaded_image);
/* Export the device path this image is started from, if it's not set yet */
- if (loaded_image->DeviceHandle &&
- 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_str16(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", uuid, 0);
+ if (loaded_image->DeviceHandle) {
+ if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", /* ret_data= */ NULL, /* ret_size= */ NULL) != EFI_SUCCESS) {
+ _cleanup_free_ char16_t *uuid = disk_get_part_uuid(loaded_image->DeviceHandle);
+ if (uuid)
+ efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", uuid, 0);
+ }
+
+ if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderDeviceURL", /* ret_data= */ NULL, /* ret_size= */ NULL) != EFI_SUCCESS) {
+ _cleanup_free_ char16_t *url = disk_get_url(loaded_image->DeviceHandle);
+ if (url)
+ efivar_set_str16(MAKE_GUID_PTR(LOADER), u"LoaderDeviceURL", url, 0);
+ }
}
/* If LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from the
'shim.c',
'smbios.c',
'ticks.c',
+ 'url-discovery.c',
'util.c',
'vmm.c',
)
MEDIA_FILEPATH_DP = 0x04,
MEDIA_PIWG_FW_FILE_DP = 0x06,
MEDIA_PIWG_FW_VOL_DP = 0x07,
+
+ MSG_URI_DP = 24,
};
struct _packed_ EFI_DEVICE_PATH_PROTOCOL {
char16_t PathName[];
} _packed_ FILEPATH_DEVICE_PATH;
+typedef struct {
+ EFI_DEVICE_PATH Header;
+ char Uri[];
+} _packed_ URI_DEVICE_PATH;
+
typedef struct {
char16_t* (EFIAPI *ConvertDeviceNodeToText)(
const EFI_DEVICE_PATH *DeviceNode,
#include "splash.h"
#include "tpm2-pcr.h"
#include "uki.h"
+#include "url-discovery.h"
#include "util.h"
#include "version.h"
#include "vmm.h"
EFI_STUB_FEATURE_DEVICETREE_ADDONS | /* We pick up .dtb addons */
EFI_STUB_FEATURE_MULTI_PROFILE_UKI | /* We grok the "@1" profile command line argument */
EFI_STUB_FEATURE_REPORT_STUB_PARTITION | /* We set StubDevicePartUUID + StubImageIdentifier */
+ EFI_STUB_FEATURE_REPORT_URL | /* We set StubDeviceURL + LoaderDeviceURL */
0;
assert(loaded_image);
_cleanup_free_ char16_t *uuid = disk_get_part_uuid(loaded_image->DeviceHandle);
if (uuid)
efivar_set_str16(MAKE_GUID_PTR(LOADER), u"StubDevicePartUUID", uuid, 0);
+
+ _cleanup_free_ char16_t *url = disk_get_url(loaded_image->DeviceHandle);
+ if (url)
+ efivar_set_str16(MAKE_GUID_PTR(LOADER), u"StubDeviceURL", url, 0);
}
if (loaded_image->FilePath) {
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "device-path-util.h"
+#include "efi-string.h"
+#include "proto/device-path.h"
+#include "url-discovery.h"
+
+char16_t *disk_get_url(EFI_HANDLE *handle) {
+ EFI_STATUS err;
+ EFI_DEVICE_PATH *dp;
+
+ /* export the device path this image is started from */
+
+ if (!handle)
+ return NULL;
+
+ err = BS->HandleProtocol(handle, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), (void **) &dp);
+ if (err != EFI_SUCCESS)
+ return NULL;
+
+ for (; !device_path_is_end(dp); dp = device_path_next_node(dp)) {
+ if (dp->Type != MESSAGING_DEVICE_PATH || dp->SubType != MSG_URI_DP)
+ continue;
+
+ URI_DEVICE_PATH *udp = (URI_DEVICE_PATH*) dp;
+ return xstrn8_to_16(udp->Uri, dp->Length);
+ }
+
+ return NULL;
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+char16_t *disk_get_url(EFI_HANDLE *handle);
{ EFI_LOADER_FEATURE_RETAIN_SHIM, "Retain SHIM protocols" },
{ EFI_LOADER_FEATURE_MENU_DISABLE, "Menu can be disabled" },
{ EFI_LOADER_FEATURE_MULTI_PROFILE_UKI, "Multi-Profile UKIs are supported" },
+ { EFI_LOADER_FEATURE_REPORT_URL, "Loader reports network boot URL" },
};
static const struct {
uint64_t flag;
const char *name;
} stub_flags[] = {
- { EFI_STUB_FEATURE_REPORT_BOOT_PARTITION, "Stub sets loader partition information" },
+ { EFI_STUB_FEATURE_REPORT_BOOT_PARTITION, "Stub reports loader partition information" },
+ { EFI_STUB_FEATURE_REPORT_STUB_PARTITION, "Stub reports stub partition information" },
+ { EFI_STUB_FEATURE_REPORT_URL, "Stub reports network boot URL" },
{ EFI_STUB_FEATURE_PICK_UP_CREDENTIALS, "Picks up credentials from boot partition" },
{ EFI_STUB_FEATURE_PICK_UP_SYSEXTS, "Picks up system extension images from boot partition" },
{ EFI_STUB_FEATURE_PICK_UP_CONFEXTS, "Picks up configuration extension images from boot partition" },
{ EFI_STUB_FEATURE_CMDLINE_SMBIOS, "Pick up .cmdline from SMBIOS Type 11" },
{ EFI_STUB_FEATURE_DEVICETREE_ADDONS, "Pick up .dtb from addons" },
{ EFI_STUB_FEATURE_MULTI_PROFILE_UKI, "Stub understands profile selector" },
- { EFI_STUB_FEATURE_REPORT_STUB_PARTITION, "Stub sets stub partition information" },
};
_cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL, *stub_path = NULL,
*current_entry = NULL, *oneshot_entry = NULL, *default_entry = NULL;
(void) efi_loader_get_device_part_uuid(&loader_partition_uuid);
print_yes_no_line(/* first= */ false, !sd_id128_is_null(loader_partition_uuid), "Boot loader set partition information");
+ _cleanup_free_ char *loader_url = NULL;
+ (void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("LoaderDeviceURL"), &loader_url);
+ print_yes_no_line(/* first= */ false, !!loader_url, "Boot loader set network boot URL information");
+
if (!sd_id128_is_null(loader_partition_uuid)) {
if (!sd_id128_is_null(esp_uuid) && !sd_id128_equal(esp_uuid, loader_partition_uuid))
printf("WARNING: The boot loader reports a different partition UUID than the detected ESP ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR")!\n",
if (loader_path)
printf(" Loader: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(loader_path));
+ if (loader_url)
+ printf(" Net Boot URL: %s\n", loader_url);
+
if (current_entry)
printf("Current Entry: %s\n", current_entry);
if (default_entry)
(void) efi_stub_get_device_part_uuid(&stub_partition_uuid);
print_yes_no_line(/* first= */ false, !sd_id128_is_null(stub_partition_uuid), "Stub loader set partition information");
+ _cleanup_free_ char *stub_url = NULL;
+ (void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE_STR("StubDeviceURL"), &stub_url);
+ print_yes_no_line(/* first= */ false, !!stub_url, "Stub set network boot URL information");
+
if (!sd_id128_is_null(stub_partition_uuid)) {
if (!(!sd_id128_is_null(esp_uuid) && sd_id128_equal(esp_uuid, stub_partition_uuid)) &&
!(!sd_id128_is_null(xbootldr_uuid) && sd_id128_equal(xbootldr_uuid, stub_partition_uuid)))
if (stub_path)
printf(" Stub: %s%s\n", special_glyph(SPECIAL_GLYPH_TREE_RIGHT), strna(stub_path));
+
+ if (stub_url)
+ printf(" Net Boot URL: %s\n", stub_url);
+
printf("\n");
}
#define EFI_LOADER_FEATURE_RETAIN_SHIM (UINT64_C(1) << 12)
#define EFI_LOADER_FEATURE_MENU_DISABLE (UINT64_C(1) << 13)
#define EFI_LOADER_FEATURE_MULTI_PROFILE_UKI (UINT64_C(1) << 14)
+#define EFI_LOADER_FEATURE_REPORT_URL (UINT64_C(1) << 15)
/* Features of the stub, i.e. systemd-stub */
#define EFI_STUB_FEATURE_REPORT_BOOT_PARTITION (UINT64_C(1) << 0)
#define EFI_STUB_FEATURE_PICK_UP_CONFEXTS (UINT64_C(1) << 8)
#define EFI_STUB_FEATURE_MULTI_PROFILE_UKI (UINT64_C(1) << 9)
#define EFI_STUB_FEATURE_REPORT_STUB_PARTITION (UINT64_C(1) << 10)
+#define EFI_STUB_FEATURE_REPORT_URL (UINT64_C(1) << 11)
typedef enum SecureBootMode {
SECURE_BOOT_UNSUPPORTED,