]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/boot/efi/stub.c
test: Disable LUKS devices from initramfs in QEMU tests
[thirdparty/systemd.git] / src / boot / efi / stub.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
0fa2cac4
KS
2
3#include <efi.h>
4#include <efilib.h>
5
8110e144 6#include "disk.h"
37fa3690 7#include "graphics.h"
0fa2cac4 8#include "linux.h"
d4cbada2
MG
9#include "measure.h"
10#include "pe.h"
cf0fbc49
TA
11#include "splash.h"
12#include "util.h"
0fa2cac4
KS
13
14/* magic string to find in the binary image */
681bd2c5 15static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
0fa2cac4
KS
16
17static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
18
19EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
20 EFI_LOADED_IMAGE *loaded_image;
a42d7cf1 21 _cleanup_freepool_ CHAR8 *b = NULL;
0fa2cac4
KS
22 UINTN size;
23 BOOLEAN secure = FALSE;
24 CHAR8 *sections[] = {
25 (UINT8 *)".cmdline",
26 (UINT8 *)".linux",
27 (UINT8 *)".initrd",
37fa3690 28 (UINT8 *)".splash",
0fa2cac4
KS
29 NULL
30 };
31 UINTN addrs[ELEMENTSOF(sections)-1] = {};
32 UINTN offs[ELEMENTSOF(sections)-1] = {};
33 UINTN szs[ELEMENTSOF(sections)-1] = {};
34 CHAR8 *cmdline = NULL;
35 UINTN cmdline_len;
8110e144 36 CHAR16 uuid[37];
0fa2cac4
KS
37 EFI_STATUS err;
38
39 InitializeLib(image, sys_table);
40
41 err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
42 image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
43 if (EFI_ERROR(err)) {
44 Print(L"Error getting a LoadedImageProtocol handle: %r ", err);
45 uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
46 return err;
47 }
48
a42d7cf1 49 if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS)
0fa2cac4
KS
50 if (*b > 0)
51 secure = TRUE;
a42d7cf1 52
d4cbada2 53 err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs);
0fa2cac4
KS
54 if (EFI_ERROR(err)) {
55 Print(L"Unable to locate embedded .linux section: %r ", err);
56 uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
57 return err;
58 }
59
60 if (szs[0] > 0)
61 cmdline = (CHAR8 *)(loaded_image->ImageBase + addrs[0]);
62
63 cmdline_len = szs[0];
64
65 /* if we are not in secure boot mode, accept a custom command line and replace the built-in one */
15720d03 66 if (!secure && loaded_image->LoadOptionsSize > 0 && *(CHAR16 *)loaded_image->LoadOptions > 0x1F) {
0fa2cac4
KS
67 CHAR16 *options;
68 CHAR8 *line;
69 UINTN i;
70
71 options = (CHAR16 *)loaded_image->LoadOptions;
72 cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8);
73 line = AllocatePool(cmdline_len);
74 for (i = 0; i < cmdline_len; i++)
75 line[i] = options[i];
76 cmdline = line;
92ed3bb4 77
349cc4a5 78#if ENABLE_TPM
7db5706e 79 /* Try to log any options to the TPM, especially manually edited options */
92ed3bb4 80 err = tpm_log_event(SD_TPM_PCR,
33de6b57 81 (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
92ed3bb4
HH
82 loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
83 if (EFI_ERROR(err)) {
84 Print(L"Unable to add image options measurement: %r", err);
522aa9f5 85 uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
92ed3bb4
HH
86 }
87#endif
0fa2cac4
KS
88 }
89
c8b32d06
LP
90 /* Export the device path this image is started from, if it's not set yet */
91 if (efivar_get_raw(&loader_guid, L"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS)
92 if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
93 efivar_set(L"LoaderDevicePartUUID", uuid, FALSE);
8110e144 94
19e0e60a 95 /* if LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from UEFI */
8118fb3c 96 if (efivar_get_raw(&loader_guid, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) {
a42d7cf1
ZJS
97 _cleanup_freepool_ CHAR16 *s;
98
99 s = DevicePathToStr(loaded_image->FilePath);
100 efivar_set(L"LoaderImageIdentifier", s, FALSE);
19e0e60a
ДГ
101 }
102
1aa15def 103 /* if LoaderFirmwareInfo is not set, let's set it */
8118fb3c 104 if (efivar_get_raw(&loader_guid, L"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) {
a42d7cf1
ZJS
105 _cleanup_freepool_ CHAR16 *s;
106
107 s = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
108 efivar_set(L"LoaderFirmwareInfo", s, FALSE);
1aa15def 109 }
a42d7cf1 110
1aa15def 111 /* ditto for LoaderFirmwareType */
8118fb3c 112 if (efivar_get_raw(&loader_guid, L"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) {
a42d7cf1
ZJS
113 _cleanup_freepool_ CHAR16 *s;
114
115 s = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
116 efivar_set(L"LoaderFirmwareType", s, FALSE);
1aa15def
ДГ
117 }
118
34412f79 119 /* add StubInfo */
8118fb3c 120 if (efivar_get_raw(&loader_guid, L"StubInfo", NULL, NULL) != EFI_SUCCESS)
681bd2c5 121 efivar_set(L"StubInfo", L"systemd-stub " GIT_VERSION, FALSE);
1aa15def 122
37fa3690
KS
123 if (szs[3] > 0)
124 graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL);
125
0fa2cac4
KS
126 err = linux_exec(image, cmdline, cmdline_len,
127 (UINTN)loaded_image->ImageBase + addrs[1],
5f7df68c 128 (UINTN)loaded_image->ImageBase + addrs[2], szs[2]);
0fa2cac4 129
37fa3690 130 graphics_mode(FALSE);
0fa2cac4
KS
131 Print(L"Execution of embedded linux image failed: %r\n", err);
132 uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
133 return err;
134}