2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/bootlib.c
5 * PURPOSE: Boot Library Initialization
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* DATA VARIABLES ************************************************************/
15 BL_LIBRARY_PARAMETERS BlpLibraryParameters
;
16 PBL_DEVICE_DESCRIPTOR BlpBootDevice
;
17 PWCHAR BlpApplicationBaseDirectory
;
18 PBOOT_APPLICATION_PARAMETER_BLOCK BlpApplicationParameters
;
19 BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
;
20 BOOLEAN BlpLibraryParametersInitialized
;
22 ULONG PdPersistAllocations
;
23 LIST_ENTRY BlBadpListHead
;
25 /* FUNCTIONS *****************************************************************/
28 * @name InitializeLibrary
30 * The InitializeLibrary function initializes the Boot Library.
32 * @param BootParameters
33 * Pointer to the Boot Application Parameter Block.
35 * @param LibraryParameters
36 * Pointer to the Boot Library Parameters.
38 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
44 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters
,
45 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
49 PBL_MEMORY_DATA MemoryData
;
50 PBL_APPLICATION_ENTRY AppEntry
;
51 PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor
;
52 ULONG_PTR ParamPointer
= (ULONG_PTR
)BootAppParameters
;
54 /* Validate correct Boot Application data */
55 if (!(BootAppParameters
) ||
56 (BootAppParameters
->Signature
[0] != BOOT_APPLICATION_SIGNATURE_1
) ||
57 (BootAppParameters
->Signature
[1] != BOOT_APPLICATION_SIGNATURE_2
) ||
58 (BootAppParameters
->Size
< sizeof(*BootAppParameters
)))
60 Status
= STATUS_INVALID_PARAMETER
;
64 /* Get sub-structures */
65 MemoryData
= (PBL_MEMORY_DATA
)(ParamPointer
+ BootAppParameters
->MemoryDataOffset
);
66 FirmwareDescriptor
= (PBL_FIRMWARE_DESCRIPTOR
)(ParamPointer
+ BootAppParameters
->FirmwareParametersOffset
);
67 AppEntry
= (PBL_APPLICATION_ENTRY
)(ParamPointer
+ BootAppParameters
->AppEntryOffset
);
68 BlpBootDevice
= (PBL_DEVICE_DESCRIPTOR
)(ParamPointer
+ BootAppParameters
->BootDeviceOffset
);
69 BlpApplicationBaseDirectory
= LibraryParameters
->ApplicationBaseDirectory
;
71 /* Initialize the firmware table */
72 Status
= BlpFwInitialize(0, FirmwareDescriptor
);
73 if (!NT_SUCCESS(Status
))
78 /* Find boot application entry */
79 if (strncmp(AppEntry
->Signature
, BL_APP_ENTRY_SIGNATURE
, 7))
81 Status
= STATUS_INVALID_PARAMETER_9
;
86 BlpApplicationParameters
= BootAppParameters
;
87 BlpLibraryParameters
= *LibraryParameters
;
89 /* Check if the caller sent us their internal BCD options */
90 if (AppEntry
->Flags
& BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL
)
92 /* These are external to us now, as far as we are concerned */
93 AppEntry
->Flags
&= ~BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL
;
94 AppEntry
->Flags
|= BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL
;
97 /* Save the application entry flags */
98 BlpApplicationEntry
.Flags
= AppEntry
->Flags
;
100 /* Copy the GUID and point to the options */
101 BlpApplicationEntry
.Guid
= AppEntry
->Guid
;
102 BlpApplicationEntry
.BcdData
= &AppEntry
->BcdData
;
104 /* Everything has been captured */
105 BlpLibraryParametersInitialized
= TRUE
;
107 /* Initialize the architecture (PM or RM) switching */
108 Status
= BlpArchInitialize(0);
109 if (!NT_SUCCESS(Status
))
114 /* Initialize the memory manager */
115 Status
= BlpMmInitialize(MemoryData
,
116 BootAppParameters
->MemoryTranslationType
,
118 if (!NT_SUCCESS(Status
))
120 EfiPrintf(L
"MM init failed!\r\n");
124 /* Initialize firmware now that the heap, etc works */
125 Status
= BlpFwInitialize(1, FirmwareDescriptor
);
126 if (!NT_SUCCESS(Status
))
128 /* Destroy memory manager in phase 1 */
130 EfiPrintf(L
"Firmware2 init failed!\r\n");
135 /* Modern systems have an undocumented BCD system for the boot frequency */
136 Status
= BlGetBootOptionInteger(BlpApplicationEntry
.BcdData
,
139 if (NT_SUCCESS(Status
) && (BootFrequency
))
141 /* Use it if present */
142 BlpTimePerformanceFrequency
= BootFrequency
;
147 /* Use the TSC for calibration */
148 Status
= BlpTimeCalibratePerformanceCounter();
149 if (!NT_SUCCESS(Status
))
151 /* Destroy memory manager in phase 1 */
152 EfiPrintf(L
"TSC calibration failed\r\n");
158 /* Now setup the rest of the architecture (IDT, etc) */
159 Status
= BlpArchInitialize(1);
160 if (!NT_SUCCESS(Status
))
162 /* Destroy memory manager in phase 1 */
163 EfiPrintf(L
"Arch2 init failed\r\n");
168 #ifdef BL_TPM_SUPPORT
169 /* Initialize support for Trusted Platform Module v1.2 */
173 #ifdef BL_TPM_SUPPORT
174 /* Initialize the event manager */
175 EnSubsystemInitialized
= 1;
176 InitializeListHead(&EnEventNotificationList
);
179 /* Initialize the I/O Manager */
180 Status
= BlpIoInitialize();
181 if (!NT_SUCCESS(Status
))
183 /* Destroy memory manager in phase 1 and the event manager */
184 EfiPrintf(L
"IO init failed\r\n");
185 #ifdef BL_TPM_SUPPORT
186 if (EnSubsystemInitialized
)
195 #ifdef BL_NET_SUPPORT
196 /* Initialize the network stack */
197 Status
= BlNetInitialize();
198 if (!NT_SUCCESS(Status
))
200 /* Destroy the I/O, event, and memory managers in phase 1 */
202 #ifdef BL_TPM_SUPPORT
203 if (EnSubsystemInitialized
)
213 /* Initialize the utility library */
214 Status
= BlUtlInitialize();
215 if (!NT_SUCCESS(Status
))
217 /* Destroy the network, I/O, event, and memory managers in phase 1 */
218 #ifdef BL_NET_SUPPORT
222 #ifdef BL_TPM_SUPPORT
223 if (EnSubsystemInitialized
)
229 EfiPrintf(L
"Util init failed\r\n");
234 /* Initialize PCI Platform Support */
235 PltInitializePciConfiguration();
238 #ifdef BL_SECURE_BOOT_SUPPORT
239 /* Read the current SecureBoot Policy*/
240 Status
= BlSecureBootSetActivePolicyFromPersistedData();
241 if (!NT_SUCCESS(Status
))
243 /* Destroy everything that we've currently set up */
245 PltDestroyPciConfiguration();
247 #ifdef BL_NET_SUPPORT
251 #ifdef BL_TPM_SUPPORT
252 if (EnSubsystemInitialized
)
262 #ifdef BL_TPM_SUPPORT
263 /* Initialize phase 0 of the security subsystem */
264 SipInitializePhase0();
268 /* Bring up the boot debugger, now that SecureBoot has been processed */
272 #ifdef BL_ETW_SUPPORT
273 /* Initialize internal logging */
277 /* Are graphics enabled? */
278 if (!(LibraryParameters
->LibraryFlags
& BL_LIBRARY_FLAG_NO_DISPLAY
))
280 /* Initialize the graphics library */
281 BlpDisplayInitialize(LibraryParameters
->LibraryFlags
);
284 /* Initialize the boot application persistent data */
285 PdPersistAllocations
= 0;
286 InitializeListHead(&BlBadpListHead
);
288 #ifdef BL_TPM_SUPPORT
289 /* Now setup the security subsystem in phase 1 */
293 /* Setup the text, UI and font resources */
294 Status
= BlpResourceInitialize();
295 if (!NT_SUCCESS(Status
))
297 /* Tear down everything if this failed */
298 if (!(LibraryParameters
->LibraryFlags
& BL_LIBRARY_FLAG_NO_DISPLAY
))
300 // BlpDisplayDestroy();
304 PltDestroyPciConfiguration();
306 #ifdef BL_NET_SUPPORT
310 #ifdef BL_TPM_SUPPORT
311 if (EnSubsystemInitialized
)
320 #if BL_BITLOCKER_SUPPORT
321 /* Setup the boot cryptography library */
322 g_pEnvironmentData
= &SymCryptEnvironmentWindowsBootLibrary
;
323 if (SymCryptEnvWindowsBootLibInit
)
325 SymCryptEnvWindowsBootLibInit();
329 /* We are fully initialized, remember this and exit with success */
330 BlpLibraryParameters
.LibraryFlags
|= BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
;
331 Status
= STATUS_SUCCESS
;
338 * @name BlInitializeLibrary
340 * The BlInitializeLibrary function initializes, or re-initializes, the
343 * @param BootParameters
344 * Pointer to the Boot Application Parameter Block.
346 * @param LibraryParameters
347 * Pointer to the Boot Library Parameters.
349 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
355 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters
,
356 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
361 /* Are we re-initializing the library? */
362 if (LibraryParameters
->LibraryFlags
& BL_LIBRARY_FLAG_REINITIALIZE
)
365 BlpLibraryParameters
= *LibraryParameters
;
366 if (LibraryParameters
->LibraryFlags
& BL_LIBRARY_FLAG_REINITIALIZE_ALL
)
368 #ifdef BL_TPM_SUPPORT
369 /* Reinitialize the TPM security enclave as BCD hash changed */
373 /* Reinitialize the boot debugger as BCD debug options changed */
377 /* Reparse the bad page list now that the BCD has been reloaded */
378 BlMmRemoveBadMemory();
380 /* Reparse the low/high physical address limits as well */
381 BlpMmInitializeConstraints();
383 /* Redraw the graphics console as needed */
384 BlpDisplayInitialize(LibraryParameters
->LibraryFlags
);
386 /* Reinitialize resources (language may have changed) */
387 BlpResourceInitialize();
390 /* Nothing to do, we're done */
391 Status
= STATUS_SUCCESS
;
395 /* Nope, this is first time initialization */
396 Status
= InitializeLibrary(BootAppParameters
, LibraryParameters
);
399 /* Return initialization status */
408 EfiPrintf(L
"Destroy not yet implemented\r\n");
413 BlGetApplicationIdentifier (
417 /* Return the GUID, if one was present */
418 return (BlpApplicationEntry
.Flags
& BL_APPLICATION_ENTRY_FLAG_NO_GUID
) ?
419 NULL
: &BlpApplicationEntry
.Guid
;
423 BlGetApplicationBaseAndSize (
424 _Out_ PVOID
* ImageBase
,
425 _Out_ PULONG ImageSize
428 /* Fail if output parameters are missing */
429 if (!ImageBase
|| !ImageSize
)
431 return STATUS_INVALID_PARAMETER
;
434 /* Return the requested data */
435 *ImageBase
= (PVOID
)(ULONG_PTR
)BlpApplicationParameters
->ImageBase
;
436 *ImageSize
= BlpApplicationParameters
->ImageSize
;
437 return STATUS_SUCCESS
;
442 _In_ PBL_LOADED_APPLICATION_ENTRY AppEntry
445 /* Check if we had allocated BCD options */
446 if (AppEntry
->Flags
& BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL
)
448 BlMmFreeHeap(AppEntry
->BcdData
);
451 /* Free the entry itself */
452 BlMmFreeHeap(AppEntry
);