1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation; either version 2.1 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * 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 " 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
;
34 CHAR16
*loaded_image_path
;
37 BOOLEAN secure
= FALSE
;
45 UINTN addrs
[ELEMENTSOF(sections
)-1] = {};
46 UINTN offs
[ELEMENTSOF(sections
)-1] = {};
47 UINTN szs
[ELEMENTSOF(sections
)-1] = {};
48 CHAR8
*cmdline
= NULL
;
53 InitializeLib(image
, sys_table
);
55 err
= uefi_call_wrapper(BS
->OpenProtocol
, 6, image
, &LoadedImageProtocol
, (VOID
**)&loaded_image
,
56 image
, NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
58 Print(L
"Error getting a LoadedImageProtocol handle: %r ", err
);
59 uefi_call_wrapper(BS
->Stall
, 1, 3 * 1000 * 1000);
63 root_dir
= LibOpenRoot(loaded_image
->DeviceHandle
);
65 Print(L
"Unable to open root directory: %r ", err
);
66 uefi_call_wrapper(BS
->Stall
, 1, 3 * 1000 * 1000);
67 return EFI_LOAD_ERROR
;
70 loaded_image_path
= DevicePathToStr(loaded_image
->FilePath
);
72 if (efivar_get_raw(&global_guid
, L
"SecureBoot", &b
, &size
) == EFI_SUCCESS
) {
78 err
= pefile_locate_sections(root_dir
, loaded_image_path
, sections
, addrs
, offs
, szs
);
80 Print(L
"Unable to locate embedded .linux section: %r ", err
);
81 uefi_call_wrapper(BS
->Stall
, 1, 3 * 1000 * 1000);
86 cmdline
= (CHAR8
*)(loaded_image
->ImageBase
+ addrs
[0]);
90 /* if we are not in secure boot mode, accept a custom command line and replace the built-in one */
91 if (!secure
&& loaded_image
->LoadOptionsSize
> 0) {
96 options
= (CHAR16
*)loaded_image
->LoadOptions
;
97 cmdline_len
= (loaded_image
->LoadOptionsSize
/ sizeof(CHAR16
)) * sizeof(CHAR8
);
98 line
= AllocatePool(cmdline_len
);
99 for (i
= 0; i
< cmdline_len
; i
++)
100 line
[i
] = options
[i
];
104 /* export the device path this image is started from */
105 if (disk_get_part_uuid(loaded_image
->DeviceHandle
, uuid
) == EFI_SUCCESS
)
106 efivar_set(L
"LoaderDevicePartUUID", uuid
, FALSE
);
109 graphics_splash((UINT8
*)((UINTN
)loaded_image
->ImageBase
+ addrs
[3]), szs
[3], NULL
);
111 err
= linux_exec(image
, cmdline
, cmdline_len
,
112 (UINTN
)loaded_image
->ImageBase
+ addrs
[1],
113 (UINTN
)loaded_image
->ImageBase
+ addrs
[2], szs
[2]);
115 graphics_mode(FALSE
);
116 Print(L
"Execution of embedded linux image failed: %r\n", err
);
117 uefi_call_wrapper(BS
->Stall
, 1, 3 * 1000 * 1000);