1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-27 18:55:40 +03:00

Merge pull request #26542 from medhefgo/boot-device-path

boot: Misc device path improvements
This commit is contained in:
Yu Watanabe 2023-02-23 10:26:40 +09:00 committed by GitHub
commit 2457a36d30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 217 additions and 240 deletions

View File

@ -3,8 +3,8 @@
#include "bcd.h"
#include "bootspec-fundamental.h"
#include "console.h"
#include "device-path-util.h"
#include "devicetree.h"
#include "disk.h"
#include "drivers.h"
#include "efivars-fundamental.h"
#include "graphics.h"
@ -2542,7 +2542,6 @@ static void export_variables(
0;
_cleanup_free_ char16_t *infostr = NULL, *typestr = NULL;
char16_t uuid[37];
assert(loaded_image);
@ -2561,7 +2560,8 @@ static void export_variables(
efivar_set(MAKE_GUID_PTR(LOADER), u"LoaderImageIdentifier", loaded_image_path, 0);
/* export the device path this image is started from */
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == 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);
}

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "cpio.h"
#include "device-path-util.h"
#include "measure.h"
#include "proto/device-path.h"
#include "util.h"
@ -310,8 +311,9 @@ static char16_t *get_dropin_dir(const EFI_DEVICE_PATH *file_path) {
* not create a legal EFI file path that the file protocol can use. */
/* Make sure we really only got file paths. */
for (const EFI_DEVICE_PATH *node = file_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node))
if (DevicePathType(node) != MEDIA_DEVICE_PATH || DevicePathSubType(node) != MEDIA_FILEPATH_DP)
for (const EFI_DEVICE_PATH *node = file_path; !device_path_is_end(node);
node = device_path_next_node(node))
if (node->Type != MEDIA_DEVICE_PATH || node->SubType != MEDIA_FILEPATH_DP)
return NULL;
_cleanup_free_ char16_t *file_path_str = NULL;

View File

@ -0,0 +1,128 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "device-path-util.h"
#include "util.h"
EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp) {
EFI_STATUS err;
EFI_DEVICE_PATH *dp;
assert(file);
assert(ret_dp);
err = BS->HandleProtocol(device, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), (void **) &dp);
if (err != EFI_SUCCESS)
return err;
EFI_DEVICE_PATH *end_node = dp;
while (!device_path_is_end(end_node))
end_node = device_path_next_node(end_node);
size_t file_size = strsize16(file);
size_t dp_size = (uint8_t *) end_node - (uint8_t *) dp;
/* Make a copy that can also hold a file media device path. */
*ret_dp = xmalloc(dp_size + file_size + sizeof(FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH));
dp = mempcpy(*ret_dp, dp, dp_size);
FILEPATH_DEVICE_PATH *file_dp = (FILEPATH_DEVICE_PATH *) dp;
file_dp->Header = (EFI_DEVICE_PATH) {
.Type = MEDIA_DEVICE_PATH,
.SubType = MEDIA_FILEPATH_DP,
.Length = sizeof(FILEPATH_DEVICE_PATH) + file_size,
};
memcpy(file_dp->PathName, file, file_size);
dp = device_path_next_node(dp);
*dp = DEVICE_PATH_END_NODE;
return EFI_SUCCESS;
}
EFI_STATUS device_path_to_str(const EFI_DEVICE_PATH *dp, char16_t **ret) {
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *dp_to_text;
EFI_STATUS err;
_cleanup_free_ char16_t *str = NULL;
assert(dp);
assert(ret);
err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_DEVICE_PATH_TO_TEXT_PROTOCOL), NULL, (void **) &dp_to_text);
if (err != EFI_SUCCESS) {
/* If the device path to text protocol is not available we can still do a best-effort attempt
* to convert it ourselves if we are given filepath-only device path. */
size_t size = 0;
for (const EFI_DEVICE_PATH *node = dp; !device_path_is_end(node);
node = device_path_next_node(node)) {
if (node->Type != MEDIA_DEVICE_PATH || node->SubType != MEDIA_FILEPATH_DP)
return err;
size_t path_size = node->Length;
if (path_size <= offsetof(FILEPATH_DEVICE_PATH, PathName) || path_size % sizeof(char16_t))
return EFI_INVALID_PARAMETER;
path_size -= offsetof(FILEPATH_DEVICE_PATH, PathName);
_cleanup_free_ char16_t *old = str;
str = xmalloc(size + path_size);
if (old) {
memcpy(str, old, size);
str[size / sizeof(char16_t) - 1] = '\\';
}
memcpy(str + (size / sizeof(char16_t)),
((uint8_t *) node) + offsetof(FILEPATH_DEVICE_PATH, PathName),
path_size);
size += path_size;
}
*ret = TAKE_PTR(str);
return EFI_SUCCESS;
}
str = dp_to_text->ConvertDevicePathToText(dp, false, false);
if (!str)
return EFI_OUT_OF_RESOURCES;
*ret = TAKE_PTR(str);
return EFI_SUCCESS;
}
bool device_path_startswith(const EFI_DEVICE_PATH *dp, const EFI_DEVICE_PATH *start) {
if (!start)
return true;
if (!dp)
return false;
for (;;) {
if (device_path_is_end(start))
return true;
if (device_path_is_end(dp))
return false;
if (start->Length != dp->Length)
return false;
if (memcmp(dp, start, start->Length) != 0)
return false;
start = device_path_next_node(start);
dp = device_path_next_node(dp);
}
}
EFI_DEVICE_PATH *device_path_replace_node(
const EFI_DEVICE_PATH *path, const EFI_DEVICE_PATH *node, const EFI_DEVICE_PATH *new_node) {
/* Create a new device path as a copy of path, while chopping off the remainder starting at the given
* node. If new_node is provided, it is appended at the end of the new path. */
assert(path);
assert(node);
size_t len = (uint8_t *) node - (uint8_t *) path;
EFI_DEVICE_PATH *ret = xmalloc(len + (new_node ? new_node->Length : 0) + sizeof(EFI_DEVICE_PATH));
EFI_DEVICE_PATH *end = mempcpy(ret, path, len);
if (new_node)
end = mempcpy(end, new_node, new_node->Length);
*end = DEVICE_PATH_END_NODE;
return ret;
}

View File

@ -0,0 +1,27 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "proto/device-path.h"
EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp);
EFI_STATUS device_path_to_str(const EFI_DEVICE_PATH *dp, char16_t **ret);
bool device_path_startswith(const EFI_DEVICE_PATH *dp, const EFI_DEVICE_PATH *start);
EFI_DEVICE_PATH *device_path_replace_node(
const EFI_DEVICE_PATH *path, const EFI_DEVICE_PATH *node, const EFI_DEVICE_PATH *new_node);
static inline EFI_DEVICE_PATH *device_path_next_node(const EFI_DEVICE_PATH *dp) {
assert(dp);
return (EFI_DEVICE_PATH *) ((uint8_t *) dp + dp->Length);
}
static inline bool device_path_is_end(const EFI_DEVICE_PATH *dp) {
assert(dp);
return dp->Type == END_DEVICE_PATH_TYPE && dp->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE;
}
#define DEVICE_PATH_END_NODE \
(EFI_DEVICE_PATH) { \
.Type = END_DEVICE_PATH_TYPE, \
.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE, \
.Length = sizeof(EFI_DEVICE_PATH) \
}

View File

@ -1,58 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "disk.h"
#include "proto/device-path.h"
#include "util.h"
EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, char16_t uuid[static 37]) {
EFI_STATUS err;
EFI_DEVICE_PATH *dp;
/* export the device path this image is started from */
if (!handle)
return EFI_NOT_FOUND;
err = BS->HandleProtocol(handle, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), (void **) &dp);
if (err != EFI_SUCCESS)
return err;
for (; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
if (DevicePathType(dp) != MEDIA_DEVICE_PATH)
continue;
if (DevicePathSubType(dp) != MEDIA_HARDDRIVE_DP)
continue;
/* The HD device path may be misaligned. */
HARDDRIVE_DEVICE_PATH hd;
memcpy(&hd, dp, MIN(sizeof(hd), (size_t) DevicePathNodeLength(dp)));
if (hd.SignatureType != SIGNATURE_TYPE_GUID)
continue;
_cleanup_free_ char16_t *tmp = xasprintf(
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
hd.Signature[3],
hd.Signature[2],
hd.Signature[1],
hd.Signature[0],
hd.Signature[5],
hd.Signature[4],
hd.Signature[7],
hd.Signature[6],
hd.Signature[8],
hd.Signature[9],
hd.Signature[10],
hd.Signature[11],
hd.Signature[12],
hd.Signature[13],
hd.Signature[14],
hd.Signature[15]);
strcpy16(uuid, tmp);
return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
}

View File

@ -1,6 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "efi.h"
EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, char16_t uuid[static 37]);

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "device-path-util.h"
#include "drivers.h"
#include "util.h"

View File

@ -332,8 +332,8 @@ efi_headers = files(
'bcd.h',
'console.h',
'cpio.h',
'device-path-util.h',
'devicetree.h',
'disk.h',
'drivers.h',
'efi-string.h',
'efi.h',
@ -367,9 +367,9 @@ efi_headers = files(
common_sources = files(
'console.c',
'device-path-util.c',
'devicetree.c',
'drivers.c',
'disk.c',
'efi-string.c',
'graphics.c',
'initrd.c',

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "device-path-util.h"
#include "part-discovery.h"
#include "proto/block-io.h"
#include "proto/device-path.h"
@ -29,31 +30,6 @@ typedef struct {
} _packed_ GptHeader;
assert_cc(sizeof(GptHeader) == 512);
static EFI_DEVICE_PATH *path_replace_hd(
const EFI_DEVICE_PATH *path,
const EFI_DEVICE_PATH *node,
const HARDDRIVE_DEVICE_PATH *new_node) {
/* Create a new device path as a copy of path, while chopping off the remainder starting at the given
* node. If new_node is provided, it is appended at the end of the new path. */
assert(path);
assert(node);
size_t len = (uint8_t *) node - (uint8_t *) path, new_node_len = 0;
if (new_node)
new_node_len = DevicePathNodeLength(&new_node->Header);
EFI_DEVICE_PATH *ret = xmalloc(len + new_node_len + sizeof(EFI_DEVICE_PATH));
EFI_DEVICE_PATH *end = mempcpy(ret, path, len);
if (new_node)
end = mempcpy(end, new_node, new_node_len);
SetDevicePathEndNode(end);
return ret;
}
static bool verify_gpt(/*const*/ GptHeader *h, EFI_LBA lba_expected) {
uint32_t crc32, crc32_saved;
EFI_STATUS err;
@ -189,11 +165,9 @@ static EFI_STATUS find_device(const EFI_GUID *type, EFI_HANDLE *device, EFI_DEVI
/* Find the (last) partition node itself. */
EFI_DEVICE_PATH *part_node = NULL;
for (EFI_DEVICE_PATH *node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
if (DevicePathType(node) != MEDIA_DEVICE_PATH)
continue;
if (DevicePathSubType(node) != MEDIA_HARDDRIVE_DP)
for (EFI_DEVICE_PATH *node = partition_path; !device_path_is_end(node);
node = device_path_next_node(node)) {
if (node->Type != MEDIA_DEVICE_PATH || node->SubType != MEDIA_HARDDRIVE_DP)
continue;
part_node = node;
@ -204,7 +178,7 @@ static EFI_STATUS find_device(const EFI_GUID *type, EFI_HANDLE *device, EFI_DEVI
/* Chop off the partition part, leaving us with the full path to the disk itself. */
_cleanup_free_ EFI_DEVICE_PATH *disk_path = NULL;
EFI_DEVICE_PATH *p = disk_path = path_replace_hd(partition_path, part_node, NULL);
EFI_DEVICE_PATH *p = disk_path = device_path_replace_node(partition_path, part_node, NULL);
EFI_HANDLE disk_handle;
EFI_BLOCK_IO_PROTOCOL *block_io;
@ -258,7 +232,7 @@ static EFI_STATUS find_device(const EFI_GUID *type, EFI_HANDLE *device, EFI_DEVI
}
/* Patch in the data we found */
*ret_device_path = path_replace_hd(partition_path, part_node, &hd);
*ret_device_path = device_path_replace_node(partition_path, part_node, (EFI_DEVICE_PATH *) &hd);
return EFI_SUCCESS;
}
@ -295,3 +269,30 @@ EFI_STATUS partition_open(const EFI_GUID *type, EFI_HANDLE *device, EFI_HANDLE *
*ret_root_dir = root_dir;
return EFI_SUCCESS;
}
char16_t *disk_get_part_uuid(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 != MEDIA_DEVICE_PATH || dp->SubType != MEDIA_HARDDRIVE_DP)
continue;
HARDDRIVE_DEVICE_PATH *hd = (HARDDRIVE_DEVICE_PATH *) dp;
if (hd->SignatureType != SIGNATURE_TYPE_GUID)
continue;
return xasprintf(GUID_FORMAT_STR, GUID_FORMAT_VAL(hd->SignatureGuid));
}
return NULL;
}

View File

@ -9,3 +9,4 @@
{ 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } }
EFI_STATUS partition_open(const EFI_GUID *type, EFI_HANDLE *device, EFI_HANDLE *ret_device, EFI_FILE **ret_root_dir);
char16_t *disk_get_part_uuid(EFI_HANDLE *handle);

View File

@ -54,7 +54,10 @@ typedef struct {
uint32_t PartitionNumber;
uint64_t PartitionStart;
uint64_t PartitionSize;
uint8_t Signature[16];
union {
uint8_t Signature[16];
EFI_GUID SignatureGuid;
};
uint8_t MBRType;
uint8_t SignatureType;
} _packed_ HARDDRIVE_DEVICE_PATH;
@ -81,24 +84,3 @@ typedef struct {
EFI_DEVICE_PATH* (EFIAPI *ConvertTextToDevicPath)(
const char16_t *ConvertTextToDevicPath);
} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;
#define DevicePathType(dp) ((dp)->Type)
#define DevicePathSubType(dp) ((dp)->SubType)
#define DevicePathNodeLength(dp) ((dp)->Length)
static inline EFI_DEVICE_PATH *NextDevicePathNode(const EFI_DEVICE_PATH *dp) {
assert(dp);
return (EFI_DEVICE_PATH *) ((uint8_t *) dp + dp->Length);
}
static inline bool IsDevicePathEnd(const EFI_DEVICE_PATH *dp) {
assert(dp);
return dp->Type == END_DEVICE_PATH_TYPE && dp->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE;
}
static inline void SetDevicePathEndNode(EFI_DEVICE_PATH *dp) {
assert(dp);
dp->Type = END_DEVICE_PATH_TYPE;
dp->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
dp->Length = sizeof(EFI_DEVICE_PATH);
}

View File

@ -8,6 +8,7 @@
* https://github.com/mjg59/efitools
*/
#include "device-path-util.h"
#include "secure-boot.h"
#include "shim.h"
#include "util.h"

View File

@ -1,8 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "cpio.h"
#include "device-path-util.h"
#include "devicetree.h"
#include "disk.h"
#include "graphics.h"
#include "linux.h"
#include "measure.h"
@ -87,14 +87,14 @@ static void export_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) {
EFI_STUB_FEATURE_RANDOM_SEED | /* We pass a random seed to the kernel */
0;
char16_t uuid[37];
assert(loaded_image);
/* Export the device path this image is started from, if it's not set yet */
if (efivar_get_raw(MAKE_GUID_PTR(LOADER), u"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS)
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
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);
}
/* If LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from the
* UEFI firmware without any boot loader, and hence set the LoaderImageIdentifier ourselves. Note

View File

@ -622,91 +622,6 @@ EFI_STATUS open_volume(EFI_HANDLE device, EFI_FILE **ret_file) {
return EFI_SUCCESS;
}
EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp) {
EFI_STATUS err;
EFI_DEVICE_PATH *dp;
assert(file);
assert(ret_dp);
err = BS->HandleProtocol(device, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), (void **) &dp);
if (err != EFI_SUCCESS)
return err;
EFI_DEVICE_PATH *end_node = dp;
while (!IsDevicePathEnd(end_node))
end_node = NextDevicePathNode(end_node);
size_t file_size = strsize16(file);
size_t dp_size = (uint8_t *) end_node - (uint8_t *) dp;
/* Make a copy that can also hold a file media device path. */
*ret_dp = xmalloc(dp_size + file_size + sizeof(FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH));
dp = mempcpy(*ret_dp, dp, dp_size);
/* Replace end node with file media device path. Use memcpy() in case dp is unaligned (if accessed as
* FILEPATH_DEVICE_PATH). */
dp->Type = MEDIA_DEVICE_PATH;
dp->SubType = MEDIA_FILEPATH_DP;
dp->Length = sizeof(FILEPATH_DEVICE_PATH) + file_size;
memcpy((uint8_t *) dp + sizeof(FILEPATH_DEVICE_PATH), file, file_size);
dp = NextDevicePathNode(dp);
SetDevicePathEndNode(dp);
return EFI_SUCCESS;
}
EFI_STATUS device_path_to_str(const EFI_DEVICE_PATH *dp, char16_t **ret) {
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *dp_to_text;
EFI_STATUS err;
_cleanup_free_ char16_t *str = NULL;
assert(dp);
assert(ret);
err = BS->LocateProtocol(MAKE_GUID_PTR(EFI_DEVICE_PATH_TO_TEXT_PROTOCOL), NULL, (void **) &dp_to_text);
if (err != EFI_SUCCESS) {
/* If the device path to text protocol is not available we can still do a best-effort attempt
* to convert it ourselves if we are given filepath-only device path. */
size_t size = 0;
for (const EFI_DEVICE_PATH *node = dp; !IsDevicePathEnd(node);
node = NextDevicePathNode(node)) {
if (DevicePathType(node) != MEDIA_DEVICE_PATH ||
DevicePathSubType(node) != MEDIA_FILEPATH_DP)
return err;
size_t path_size = DevicePathNodeLength(node);
if (path_size <= offsetof(FILEPATH_DEVICE_PATH, PathName) || path_size % sizeof(char16_t))
return EFI_INVALID_PARAMETER;
path_size -= offsetof(FILEPATH_DEVICE_PATH, PathName);
_cleanup_free_ char16_t *old = str;
str = xmalloc(size + path_size);
if (old) {
memcpy(str, old, size);
str[size / sizeof(char16_t) - 1] = '\\';
}
memcpy(str + (size / sizeof(char16_t)),
((uint8_t *) node) + offsetof(FILEPATH_DEVICE_PATH, PathName),
path_size);
size += path_size;
}
*ret = TAKE_PTR(str);
return EFI_SUCCESS;
}
str = dp_to_text->ConvertDevicePathToText(dp, false, false);
if (!str)
return EFI_OUT_OF_RESOURCES;
*ret = TAKE_PTR(str);
return EFI_SUCCESS;
}
void *find_configuration_table(const EFI_GUID *guid) {
for (size_t i = 0; i < ST->NumberOfTableEntries; i++)
if (efi_guid_equal(&ST->ConfigurationTable[i].VendorGuid, guid))

View File

@ -119,6 +119,11 @@ static inline void unload_imagep(EFI_HANDLE *image) {
#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], \
(g).Data4[2], (g).Data4[3], (g).Data4[4], (g).Data4[5], (g).Data4[6], (g).Data4[7]
void print_at(size_t x, size_t y, size_t attr, const char16_t *str);
void clear_screen(size_t attr);
@ -184,8 +189,6 @@ static inline void beep(unsigned beep_count) {}
#endif
EFI_STATUS open_volume(EFI_HANDLE device, EFI_FILE **ret_file);
EFI_STATUS make_file_device_path(EFI_HANDLE device, const char16_t *file, EFI_DEVICE_PATH **ret_dp);
EFI_STATUS device_path_to_str(const EFI_DEVICE_PATH *dp, char16_t **ret);
static inline bool efi_guid_equal(const EFI_GUID *a, const EFI_GUID *b) {
return memcmp(a, b, sizeof(EFI_GUID)) == 0;

View File

@ -4,6 +4,7 @@
# include <cpuid.h>
#endif
#include "device-path-util.h"
#include "drivers.h"
#include "efi-string.h"
#include "proto/device-path.h"
@ -19,7 +20,7 @@
/* detect direct boot */
bool is_direct_boot(EFI_HANDLE device) {
EFI_STATUS err;
VENDOR_DEVICE_PATH *dp; /* NB: Alignment of this structure might be quirky! */
VENDOR_DEVICE_PATH *dp;
err = BS->HandleProtocol(device, MAKE_GUID_PTR(EFI_DEVICE_PATH_PROTOCOL), (void **) &dp);
if (err != EFI_SUCCESS)
@ -28,7 +29,7 @@ bool is_direct_boot(EFI_HANDLE device) {
/* 'qemu -kernel systemd-bootx64.efi' */
if (dp->Header.Type == MEDIA_DEVICE_PATH &&
dp->Header.SubType == MEDIA_VENDOR_DP &&
memcmp(&dp->Guid, MAKE_GUID_PTR(QEMU_KERNEL_LOADER_FS_MEDIA), sizeof(EFI_GUID)) == 0) /* Don't change to efi_guid_equal() because EFI device path objects are not necessarily aligned! */
memcmp(&dp->Guid, MAKE_GUID_PTR(QEMU_KERNEL_LOADER_FS_MEDIA), sizeof(EFI_GUID)) == 0)
return true;
/* loaded from firmware volume (sd-boot added to ovmf) */
@ -39,27 +40,6 @@ bool is_direct_boot(EFI_HANDLE device) {
return false;
}
static bool device_path_startswith(const EFI_DEVICE_PATH *dp, const EFI_DEVICE_PATH *start) {
if (!start)
return true;
if (!dp)
return false;
for (;;) {
if (IsDevicePathEnd(start))
return true;
if (IsDevicePathEnd(dp))
return false;
size_t l1 = DevicePathNodeLength(start);
size_t l2 = DevicePathNodeLength(dp);
if (l1 != l2)
return false;
if (memcmp(dp, start, l1) != 0)
return false;
start = NextDevicePathNode(start);
dp = NextDevicePathNode(dp);
}
}
/*
* Try find ESP when not loaded from ESP
*