OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
Bootstrap.c
Go to the documentation of this file.
1
15#include <Library/OcMainLib.h>
16#include <Uefi.h>
17
18#include <Protocol/DevicePath.h>
19#include <Protocol/LoadedImage.h>
20
21#include <Library/UefiLib.h>
22#include <Library/BaseMemoryLib.h>
24#include <Library/DevicePathLib.h>
25#include <Library/MemoryAllocationLib.h>
27#include <Library/OcFileLib.h>
28#include <Library/OcStringLib.h>
29#include <Library/UefiBootServicesTableLib.h>
30#include <Library/UefiRuntimeServicesTableLib.h>
31#include <Library/UefiApplicationEntryPoint.h>
32
33STATIC
34EFI_STATUS
36 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
37 IN EFI_HANDLE DeviceHandle,
38 IN EFI_DEVICE_PATH_PROTOCOL *LoaderDevicePath
39 )
40{
41 EFI_STATUS Status;
42 VOID *Buffer;
43 UINTN LoaderPathSize;
44 UINTN PrefixPathSize;
45 UINTN RootPathLength;
46 CHAR16 *LoaderPath;
47 UINT32 BufferSize;
48 EFI_DEVICE_PATH_PROTOCOL *ImagePath;
49
50 ASSERT (FileSystem != NULL);
51
52 Buffer = NULL;
53 BufferSize = 0;
54
55 LoaderPath = OcCopyDevicePathFullName (LoaderDevicePath, NULL);
56
57 ImagePath = NULL;
58
59 //
60 // Try relative path: EFI\\XXX\\Subdir\\Launcher.efi -> EFI\\XXX\\OpenCore.efi
61 //
62 if (LoaderPath != NULL) {
63 LoaderPathSize = StrSize (LoaderPath);
64 if ( UnicodeGetParentDirectory (LoaderPath)
65 && UnicodeGetParentDirectory (LoaderPath))
66 {
67 DEBUG ((DEBUG_INFO, "BS: Relative path - %s\n", LoaderPath));
68 PrefixPathSize = StrSize (LoaderPath);
69 if (LoaderPathSize - PrefixPathSize >= L_STR_SIZE (OPEN_CORE_APP_PATH)) {
70 RootPathLength = PrefixPathSize / sizeof (CHAR16) - 1;
71 LoaderPath[RootPathLength] = '\\';
72 CopyMem (&LoaderPath[RootPathLength + 1], OPEN_CORE_APP_PATH, L_STR_SIZE (OPEN_CORE_APP_PATH));
73 Buffer = OcReadFile (FileSystem, LoaderPath, &BufferSize, BASE_16MB);
74 DEBUG ((DEBUG_INFO, "BS: Startup path - %s (%p)\n", LoaderPath, Buffer));
75
76 if (Buffer != NULL) {
77 ImagePath = FileDevicePath (DeviceHandle, LoaderPath);
78 if (ImagePath == NULL) {
79 DEBUG ((DEBUG_INFO, "BS: File DP allocation failure, aborting\n"));
80 FreePool (Buffer);
81 Buffer = NULL;
82 }
83 }
84 }
85 }
86
87 FreePool (LoaderPath);
88 }
89
90 //
91 // Try absolute path: EFI\\BOOT\\BOOTx64.efi -> EFI\\OC\\OpenCore.efi
92 //
93 if (Buffer == NULL) {
94 DEBUG ((
95 DEBUG_INFO,
96 "BS: Fallback to absolute path - %s\n",
98 ));
99
101 FileSystem,
103 &BufferSize,
104 BASE_16MB
105 );
106 if (Buffer != NULL) {
107 //
108 // Failure to allocate this one is not too critical, as we will still be able
109 // to choose it as a default path.
110 //
111 ImagePath = FileDevicePath (DeviceHandle, OPEN_CORE_ROOT_PATH L"\\" OPEN_CORE_APP_PATH);
112 }
113 }
114
115 if (Buffer == NULL) {
116 ASSERT (ImagePath == NULL);
117 DEBUG ((DEBUG_ERROR, "BS: Failed to locate valid OpenCore image - %p!\n", Buffer));
118 return EFI_NOT_FOUND;
119 }
120
121 DEBUG ((DEBUG_INFO, "BS: Read OpenCore image of %Lu bytes\n", (UINT64)BufferSize));
122
123 //
124 // Run OpenCore image
125 //
126 Status = OcLoadAndRunImage (
127 ImagePath,
128 Buffer,
129 BufferSize,
130 NULL,
131 NULL
132 );
133
134 DEBUG ((DEBUG_ERROR, "BS: Failed to start OpenCore image - %r\n", Status));
135 FreePool (Buffer);
136 FreePool (ImagePath);
137
138 return Status;
139}
140
141EFI_STATUS
142EFIAPI
144 IN EFI_HANDLE ImageHandle,
145 IN EFI_SYSTEM_TABLE *SystemTable
146 )
147{
148 EFI_STATUS Status;
149 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
150 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
151
152 DEBUG ((DEBUG_INFO, "BS: Starting OpenCore application...\n"));
153
154 //
155 // We have just started at EFI/BOOT/BOOTx64.efi.
156 // We need to run OpenCore on this partition as it failed automatically.
157 // The image is optionally located at OPEN_CORE_APP_PATH file.
158 //
159
160 LoadedImage = NULL;
161 Status = gBS->HandleProtocol (
162 ImageHandle,
164 (VOID **)&LoadedImage
165 );
166
167 if (EFI_ERROR (Status)) {
168 DEBUG ((DEBUG_ERROR, "BS: Failed to locate loaded image - %r\n", Status));
169 return EFI_NOT_FOUND;
170 }
171
172 DebugPrintDevicePath (DEBUG_INFO, "BS: Booter path", LoadedImage->FilePath);
173
174 //
175 // Obtain the file system device path
176 //
177 FileSystem = OcLocateFileSystem (
178 LoadedImage->DeviceHandle,
179 LoadedImage->FilePath
180 );
181
182 if (FileSystem == NULL) {
183 DEBUG ((DEBUG_ERROR, "BS: Failed to obtain own file system\n"));
184 return EFI_NOT_FOUND;
185 }
186
187 DEBUG ((DEBUG_INFO, "BS: Trying to load OpenCore image...\n"));
188 Status = LoadOpenCore (FileSystem, LoadedImage->DeviceHandle, LoadedImage->FilePath);
189 DEBUG ((DEBUG_WARN, "BS: Failed to load OpenCore from disk - %r\n", Status));
190 return Status;
191}
STATIC EFI_STATUS LoadOpenCore(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN EFI_HANDLE DeviceHandle, IN EFI_DEVICE_PATH_PROTOCOL *LoaderDevicePath)
Definition Bootstrap.c:35
EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition Bootstrap.c:143
EFI_BOOT_SERVICES * gBS
VOID DebugPrintDevicePath(IN UINTN ErrorLevel, IN CONST CHAR8 *Message, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL)
CHAR16 * OcCopyDevicePathFullName(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT EFI_DEVICE_PATH_PROTOCOL **FileDevicePath OPTIONAL)
VOID * OcReadFile(IN CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem, IN CONST CHAR16 *FilePath, OUT UINT32 *FileSize OPTIONAL, IN CONST UINT32 MaxFileSize OPTIONAL)
Definition ReadFile.c:33
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * OcLocateFileSystem(IN EFI_HANDLE DeviceHandle OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL)
#define OPEN_CORE_APP_PATH
Definition OcMainLib.h:50
#define OPEN_CORE_ROOT_PATH
Definition OcMainLib.h:48
EFI_STATUS OcLoadAndRunImage(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN VOID *Buffer OPTIONAL, IN UINTN BufferSize, OUT EFI_HANDLE *ImageHandle OPTIONAL, IN CHAR16 *OptionalData OPTIONAL)
Definition ImageRunner.c:25
#define L_STR_SIZE(String)
Definition OcStringLib.h:35
BOOLEAN UnicodeGetParentDirectory(IN OUT CHAR16 *String)
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_GUID gEfiLoadedImageProtocolGuid
#define ASSERT(x)
Definition coder.h:55