1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /* This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation; either version 2.1 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * Copyright (C) 2015 Kay Sievers <kay@vrfy.org>
26 /* magic string to find in the binary image */
27 static const char __attribute__((used
)) magic
[] = "#### LoaderInfo: systemd-stub " PACKAGE_VERSION
" ####";
29 static const EFI_GUID global_guid
= EFI_GLOBAL_VARIABLE
;
31 EFI_STATUS
efi_main(EFI_HANDLE image
, EFI_SYSTEM_TABLE
*sys_table
) {
32 EFI_LOADED_IMAGE
*loaded_image
;
35 BOOLEAN secure
= FALSE
;
43 UINTN addrs
[ELEMENTSOF(sections
)-1] = {};
44 UINTN offs
[ELEMENTSOF(sections
)-1] = {};
45 UINTN szs
[ELEMENTSOF(sections
)-1] = {};
46 CHAR8
*cmdline
= NULL
;
51 InitializeLib(image
, sys_table
);
53 err
= uefi_call_wrapper(BS
->OpenProtocol
, 6, image
, &LoadedImageProtocol
, (VOID
**)&loaded_image
,
54 image
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
56 Print(L
"Error getting a LoadedImageProtocol handle: %r ", err
);
57 uefi_call_wrapper(BS
->Stall
, 1, 3 * 1000 * 1000);
61 if (efivar_get_raw(&global_guid
, L
"SecureBoot", &b
, &size
) == EFI_SUCCESS
) {
66 err
= pe_memory_locate_sections(loaded_image
->ImageBase
, sections
, addrs
, offs
, szs
);
68 Print(L
"Unable to locate embedded .linux section: %r ", err
);
69 uefi_call_wrapper(BS
->Stall
, 1, 3 * 1000 * 1000);
74 cmdline
= (CHAR8
*)(loaded_image
->ImageBase
+ addrs
[0]);
78 /* if we are not in secure boot mode, accept a custom command line and replace the built-in one */
79 if (!secure
&& loaded_image
->LoadOptionsSize
> 0 && *(CHAR16
*)loaded_image
->LoadOptions
!= 0) {
84 options
= (CHAR16
*)loaded_image
->LoadOptions
;
85 cmdline_len
= (loaded_image
->LoadOptionsSize
/ sizeof(CHAR16
)) * sizeof(CHAR8
);
86 line
= AllocatePool(cmdline_len
);
87 for (i
= 0; i
< cmdline_len
; i
++)
92 /* Try to log any options to the TPM, especially manually edited options */
93 err
= tpm_log_event(SD_TPM_PCR
,
94 (EFI_PHYSICAL_ADDRESS
) loaded_image
->LoadOptions
,
95 loaded_image
->LoadOptionsSize
, loaded_image
->LoadOptions
);
97 Print(L
"Unable to add image options measurement: %r", err
);
98 uefi_call_wrapper(BS
->Stall
, 1, 200 * 1000);
103 /* export the device path this image is started from */
104 if (disk_get_part_uuid(loaded_image
->DeviceHandle
, uuid
) == EFI_SUCCESS
)
105 efivar_set(L
"LoaderDevicePartUUID", uuid
, FALSE
);
108 graphics_splash((UINT8
*)((UINTN
)loaded_image
->ImageBase
+ addrs
[3]), szs
[3], NULL
);
110 err
= linux_exec(image
, cmdline
, cmdline_len
,
111 (UINTN
)loaded_image
->ImageBase
+ addrs
[1],
112 (UINTN
)loaded_image
->ImageBase
+ addrs
[2], szs
[2]);
114 graphics_mode(FALSE
);
115 Print(L
"Execution of embedded linux image failed: %r\n", err
);
116 uefi_call_wrapper(BS
->Stall
, 1, 3 * 1000 * 1000);