1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
// SPDX-License-Identifier: GPL-2.0
#include <generated/utsrelease.h>
#include <linux/efi.h>
#include <linux/unaligned.h>
#include "efistub.h"
static efi_guid_t loader_entry_guid = LINUX_EFI_LOADER_ENTRY_GUID;
static const struct efi_hd_dev_path *
efi_bli_find_hd_node(const struct efi_dev_path *path)
{
const struct efi_dev_path *node;
u16 node_len;
for (node = path;
node->header.type != EFI_DEV_END_PATH &&
node->header.type != EFI_DEV_END_PATH2;
node = (const void *)node + node_len) {
node_len = get_unaligned_le16(&node->header.length);
if (node_len < sizeof(node->header))
return NULL;
if (node->header.type != EFI_DEV_MEDIA ||
node->header.sub_type != EFI_DEV_MEDIA_HARD_DRIVE)
continue;
if (node_len < sizeof(node->hd))
return NULL;
if (node->hd.partition_format != EFI_HD_PARTITION_FORMAT_GPT ||
node->hd.signature_type != EFI_HD_SIGNATURE_TYPE_GUID)
continue;
return &node->hd;
}
return NULL;
}
static void efi_bli_populate_loader_part_uuid(const efi_loaded_image_t *image)
{
static efi_guid_t device_path_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
efi_char16_t partuuid[UUID_STRING_LEN + 1];
const struct efi_hd_dev_path *hd_node;
const struct efi_dev_path *path;
if (efi_bs_call(handle_protocol, efi_table_attr(image, device_handle),
&device_path_guid, (void **)&path) != EFI_SUCCESS)
return;
hd_node = efi_bli_find_hd_node(path);
if (!hd_node)
return;
if (efi_snprintf(partuuid, ARRAY_SIZE(partuuid), "%pUl",
&hd_node->signature) != UUID_STRING_LEN)
return;
set_efi_var(L"LoaderDevicePartUUID", &loader_entry_guid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(partuuid), partuuid);
}
void efi_bli_set_variables(const efi_loaded_image_t *image)
{
static efi_char16_t loader_info[] = L"Linux EFI stub " UTS_RELEASE;
unsigned long size = 0;
if (!image)
return;
if (get_efi_var(L"LoaderInfo", &loader_entry_guid,
NULL, &size, NULL) != EFI_NOT_FOUND)
return;
if (set_efi_var(L"LoaderInfo", &loader_entry_guid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
sizeof(loader_info), loader_info) != EFI_SUCCESS)
return;
efi_bli_populate_loader_part_uuid(image);
}
|