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
;
21 ULONG BlpApplicationFlags
;
23 ULONG PdPersistAllocations
;
24 LIST_ENTRY BlpPdListHead
;
26 /* FUNCTIONS *****************************************************************/
29 * @name InitializeLibrary
31 * The InitializeLibrary function initializes the Boot Library.
33 * @param BootParameters
34 * Pointer to the Boot Application Parameter Block.
36 * @param LibraryParameters
37 * Pointer to the Boot Library Parameters.
39 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
45 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters
,
46 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
50 PBL_MEMORY_DATA MemoryData
;
51 PBL_APPLICATION_ENTRY AppEntry
;
52 PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor
;
53 LARGE_INTEGER BootFrequency
;
54 ULONG_PTR ParamPointer
;
56 /* Validate correct Boot Application data */
57 ParamPointer
= (ULONG_PTR
)BootAppParameters
;
58 if (!(BootAppParameters
) ||
59 (BootAppParameters
->Signature
[0] != BOOT_APPLICATION_SIGNATURE_1
) ||
60 (BootAppParameters
->Signature
[1] != BOOT_APPLICATION_SIGNATURE_2
) ||
61 (BootAppParameters
->Size
< sizeof(*BootAppParameters
)))
63 Status
= STATUS_INVALID_PARAMETER
;
67 /* Get sub-structures */
68 MemoryData
= (PBL_MEMORY_DATA
)(ParamPointer
+ BootAppParameters
->MemoryDataOffset
);
69 FirmwareDescriptor
= (PBL_FIRMWARE_DESCRIPTOR
)(ParamPointer
+ BootAppParameters
->FirmwareParametersOffset
);
70 AppEntry
= (PBL_APPLICATION_ENTRY
)(ParamPointer
+ BootAppParameters
->AppEntryOffset
);
71 BlpBootDevice
= (PBL_DEVICE_DESCRIPTOR
)(ParamPointer
+ BootAppParameters
->BootDeviceOffset
);
72 BlpApplicationBaseDirectory
= LibraryParameters
->ApplicationBaseDirectory
;
74 /* Initialize the firmware table */
75 Status
= BlpFwInitialize(0, FirmwareDescriptor
);
76 if (!NT_SUCCESS(Status
))
81 /* Find boot application entry */
82 if (strncmp(AppEntry
->Signature
, BL_APP_ENTRY_SIGNATURE
, 7))
84 Status
= STATUS_INVALID_PARAMETER_9
;
89 BlpApplicationParameters
= BootAppParameters
;
90 BlpLibraryParameters
= *LibraryParameters
;
92 /* Check if the caller sent us their internal BCD options */
93 if (AppEntry
->Flags
& BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL
)
95 /* These are external to us now, as far as we are concerned */
96 AppEntry
->Flags
&= ~BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL
;
97 AppEntry
->Flags
|= BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL
;
100 /* Save the application entry flags */
101 BlpApplicationEntry
.Flags
= AppEntry
->Flags
;
103 /* Copy the GUID and point to the options */
104 BlpApplicationEntry
.Guid
= AppEntry
->Guid
;
105 BlpApplicationEntry
.BcdData
= &AppEntry
->BcdData
;
107 /* Everything has been captured */
108 BlpLibraryParametersInitialized
= TRUE
;
110 /* Initialize the architecture (PM or RM) switching */
111 Status
= BlpArchInitialize(0);
112 if (!NT_SUCCESS(Status
))
117 /* Initialize the memory manager */
118 Status
= BlpMmInitialize(MemoryData
,
119 BootAppParameters
->MemoryTranslationType
,
121 if (!NT_SUCCESS(Status
))
123 EfiPrintf(L
"MM init failed!\r\n");
127 /* Initialize firmware now that the heap, etc works */
128 Status
= BlpFwInitialize(1, FirmwareDescriptor
);
129 if (!NT_SUCCESS(Status
))
131 /* Destroy memory manager in phase 1 */
133 EfiPrintf(L
"Firmware2 init failed!\r\n");
137 /* Modern systems have an undocumented BCD system for the boot frequency */
138 Status
= BlGetBootOptionInteger(BlpApplicationEntry
.BcdData
,
140 (PULONGLONG
)&BootFrequency
.QuadPart
);
141 if (NT_SUCCESS(Status
) && (BootFrequency
.QuadPart
))
143 /* Use it if present */
144 BlpTimePerformanceFrequency
= BootFrequency
.QuadPart
;
148 /* Use the TSC for calibration */
149 Status
= BlpTimeCalibratePerformanceCounter();
150 if (!NT_SUCCESS(Status
))
152 /* Destroy memory manager in phase 1 */
153 EfiPrintf(L
"TSC calibration failed\r\n");
159 /* Now setup the rest of the architecture (IDT, etc) */
160 Status
= BlpArchInitialize(1);
161 if (!NT_SUCCESS(Status
))
163 /* Destroy memory manager in phase 1 */
164 EfiPrintf(L
"Arch2 init failed\r\n");
169 #ifdef BL_TPM_SUPPORT
170 /* Initialize support for Trusted Platform Module v1.2 */
174 #ifdef BL_TPM_SUPPORT
175 /* Initialize the event manager */
176 EnSubsystemInitialized
= 1;
177 InitializeListHead(&EnEventNotificationList
);
180 /* Initialize the I/O Manager */
181 Status
= BlpIoInitialize();
182 if (!NT_SUCCESS(Status
))
184 /* Destroy memory manager in phase 1 and the event manager */
185 EfiPrintf(L
"IO init failed\r\n");
186 #ifdef BL_TPM_SUPPORT
187 if (EnSubsystemInitialized
)
196 #ifdef BL_NET_SUPPORT
197 /* Initialize the network stack */
198 Status
= BlNetInitialize();
199 if (!NT_SUCCESS(Status
))
201 /* Destroy the I/O, event, and memory managers in phase 1 */
203 #ifdef BL_TPM_SUPPORT
204 if (EnSubsystemInitialized
)
214 /* Initialize the utility library */
215 Status
= BlUtlInitialize();
216 if (!NT_SUCCESS(Status
))
218 /* Destroy the network, I/O, event, and memory managers in phase 1 */
219 #ifdef BL_NET_SUPPORT
223 #ifdef BL_TPM_SUPPORT
224 if (EnSubsystemInitialized
)
230 EfiPrintf(L
"Util init failed\r\n");
235 /* Initialize PCI Platform Support */
236 PltInitializePciConfiguration();
239 #ifdef BL_SECURE_BOOT_SUPPORT
240 /* Read the current SecureBoot Policy*/
241 Status
= BlSecureBootSetActivePolicyFromPersistedData();
242 if (!NT_SUCCESS(Status
))
244 /* Destroy everything that we've currently set up */
246 PltDestroyPciConfiguration();
248 #ifdef BL_NET_SUPPORT
252 #ifdef BL_TPM_SUPPORT
253 if (EnSubsystemInitialized
)
263 #ifdef BL_TPM_SUPPORT
264 /* Initialize phase 0 of the security subsystem */
265 SipInitializePhase0();
269 /* Bring up the boot debugger, now that SecureBoot has been processed */
273 #ifdef BL_ETW_SUPPORT
274 /* Initialize internal logging */
278 /* Are graphics enabled? */
279 if (!(LibraryParameters
->LibraryFlags
& BL_LIBRARY_FLAG_NO_DISPLAY
))
281 /* Initialize the graphics library */
282 BlpDisplayInitialize(LibraryParameters
->LibraryFlags
);
285 /* Initialize the boot application persistent data */
286 PdPersistAllocations
= 0;
287 InitializeListHead(&BlpPdListHead
);
289 #ifdef BL_TPM_SUPPORT
290 /* Now setup the security subsystem in phase 1 */
294 /* Setup the text, UI and font resources */
295 Status
= BlpResourceInitialize();
296 if (!NT_SUCCESS(Status
))
298 /* Tear down everything if this failed */
299 if (!(LibraryParameters
->LibraryFlags
& BL_LIBRARY_FLAG_NO_DISPLAY
))
301 // BlpDisplayDestroy();
305 PltDestroyPciConfiguration();
307 #ifdef BL_NET_SUPPORT
311 #ifdef BL_TPM_SUPPORT
312 if (EnSubsystemInitialized
)
321 #if BL_BITLOCKER_SUPPORT
322 /* Setup the boot cryptography library */
323 g_pEnvironmentData
= &SymCryptEnvironmentWindowsBootLibrary
;
324 if (SymCryptEnvWindowsBootLibInit
)
326 SymCryptEnvWindowsBootLibInit();
330 /* We are fully initialized, remember this and exit with success */
331 BlpLibraryParameters
.LibraryFlags
|= BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
;
332 Status
= STATUS_SUCCESS
;
339 * @name BlInitializeLibrary
341 * The BlInitializeLibrary function initializes, or re-initializes, the
344 * @param BootParameters
345 * Pointer to the Boot Application Parameter Block.
347 * @param LibraryParameters
348 * Pointer to the Boot Library Parameters.
350 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
356 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters
,
357 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
362 /* Are we re-initializing the library? */
363 if (LibraryParameters
->LibraryFlags
& BL_LIBRARY_FLAG_REINITIALIZE
)
366 BlpLibraryParameters
= *LibraryParameters
;
367 if (LibraryParameters
->LibraryFlags
& BL_LIBRARY_FLAG_REINITIALIZE_ALL
)
369 #ifdef BL_TPM_SUPPORT
370 /* Reinitialize the TPM security enclave as BCD hash changed */
374 /* Reinitialize the boot debugger as BCD debug options changed */
378 /* Reparse the bad page list now that the BCD has been reloaded */
379 BlMmRemoveBadMemory();
381 /* Reparse the low/high physical address limits as well */
382 BlpMmInitializeConstraints();
384 /* Redraw the graphics console as needed */
385 BlpDisplayInitialize(LibraryParameters
->LibraryFlags
);
387 /* Reinitialize resources (language may have changed) */
388 BlpResourceInitialize();
391 /* Nothing to do, we're done */
392 Status
= STATUS_SUCCESS
;
396 /* Nope, this is first time initialization */
397 Status
= InitializeLibrary(BootAppParameters
, LibraryParameters
);
400 /* Return initialization status */
409 EfiPrintf(L
"Destroy not yet implemented\r\n");
414 BlGetApplicationIdentifier (
418 /* Return the GUID, if one was present */
419 return (BlpApplicationEntry
.Flags
& BL_APPLICATION_ENTRY_FLAG_NO_GUID
) ?
420 NULL
: &BlpApplicationEntry
.Guid
;
424 BlGetApplicationBaseAndSize (
425 _Out_ PVOID
* ImageBase
,
426 _Out_ PULONG ImageSize
429 /* Fail if output parameters are missing */
430 if (!ImageBase
|| !ImageSize
)
432 return STATUS_INVALID_PARAMETER
;
435 /* Return the requested data */
436 *ImageBase
= (PVOID
)(ULONG_PTR
)BlpApplicationParameters
->ImageBase
;
437 *ImageSize
= BlpApplicationParameters
->ImageSize
;
438 return STATUS_SUCCESS
;
443 _In_ PBL_LOADED_APPLICATION_ENTRY AppEntry
446 /* Check if we had allocated BCD options */
447 if (AppEntry
->Flags
& BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL
)
449 BlMmFreeHeap(AppEntry
->BcdData
);
452 /* Free the entry itself */
453 BlMmFreeHeap(AppEntry
);
458 _In_
const GUID
* DataGuid
,
460 _Inout_ PBL_PD_DATA_BLOB DataBlob
463 /* Check for invalid or missing parameters */
466 ((DataBlob
->BlobSize
) && !(DataBlob
->Data
)))
468 return STATUS_INVALID_PARAMETER
;
471 /* Check if there's no persistent data blobs */
472 if (IsListEmpty(&BlpPdListHead
))
474 return STATUS_NOT_FOUND
;
477 /* Not yet handled, TODO */
478 EfiPrintf(L
"Boot persistent data not yet implemented\r\n");
479 return STATUS_NOT_IMPLEMENTED
;