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