ReactOS 0.4.15-dev-7958-gcd0bb1a
bootlib.c
Go to the documentation of this file.
1/*
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)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include "bl.h"
12
13/* DATA VARIABLES ************************************************************/
14
22
25
26/* FUNCTIONS *****************************************************************/
27
28/*++
29 * @name InitializeLibrary
30 *
31 * The InitializeLibrary function initializes the Boot Library.
32 *
33 * @param BootParameters
34 * Pointer to the Boot Application Parameter Block.
35 *
36 * @param LibraryParameters
37 * Pointer to the Boot Library Parameters.
38 *
39 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
40 * otherwise.
41 *
42 *--*/
46 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
47 )
48{
50 PBL_MEMORY_DATA MemoryData;
51 PBL_APPLICATION_ENTRY AppEntry;
52 PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor;
53 LARGE_INTEGER BootFrequency;
54 ULONG_PTR ParamPointer;
55
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)))
62 {
64 goto Quickie;
65 }
66
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;
73
74 /* Initialize the firmware table */
75 Status = BlpFwInitialize(0, FirmwareDescriptor);
76 if (!NT_SUCCESS(Status))
77 {
78 goto Quickie;
79 }
80
81 /* Find boot application entry */
82 if (strncmp(AppEntry->Signature, BL_APP_ENTRY_SIGNATURE, 7))
83 {
85 goto Quickie;
86 }
87
88 /* Read parameters */
89 BlpApplicationParameters = BootAppParameters;
90 BlpLibraryParameters = *LibraryParameters;
91
92 /* Check if the caller sent us their internal BCD options */
94 {
95 /* These are external to us now, as far as we are concerned */
96 AppEntry->Flags &= ~BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL;
98 }
99
100 /* Save the application entry flags */
101 BlpApplicationEntry.Flags = AppEntry->Flags;
102
103 /* Copy the GUID and point to the options */
104 BlpApplicationEntry.Guid = AppEntry->Guid;
106
107 /* Everything has been captured */
109
110 /* Initialize the architecture (PM or RM) switching */
112 if (!NT_SUCCESS(Status))
113 {
114 goto Quickie;
115 }
116
117 /* Initialize the memory manager */
118 Status = BlpMmInitialize(MemoryData,
119 BootAppParameters->MemoryTranslationType,
120 LibraryParameters);
121 if (!NT_SUCCESS(Status))
122 {
123 EfiPrintf(L"MM init failed!\r\n");
124 goto Quickie;
125 }
126
127 /* Initialize firmware now that the heap, etc works */
128 Status = BlpFwInitialize(1, FirmwareDescriptor);
129 if (!NT_SUCCESS(Status))
130 {
131 /* Destroy memory manager in phase 1 */
132 //BlpMmDestroy(1);
133 EfiPrintf(L"Firmware2 init failed!\r\n");
134 return Status;
135 }
136
137 /* Modern systems have an undocumented BCD system for the boot frequency */
139 0x15000075,
140 (PULONGLONG)&BootFrequency.QuadPart);
141 if (NT_SUCCESS(Status) && (BootFrequency.QuadPart))
142 {
143 /* Use it if present */
145 }
146 else
147 {
148 /* Use the TSC for calibration */
150 if (!NT_SUCCESS(Status))
151 {
152 /* Destroy memory manager in phase 1 */
153 EfiPrintf(L"TSC calibration failed\r\n");
154 //BlpMmDestroy(1);
155 return Status;
156 }
157 }
158
159 /* Now setup the rest of the architecture (IDT, etc) */
161 if (!NT_SUCCESS(Status))
162 {
163 /* Destroy memory manager in phase 1 */
164 EfiPrintf(L"Arch2 init failed\r\n");
165 //BlpMmDestroy(1);
166 return Status;
167 }
168
169#ifdef BL_TPM_SUPPORT
170 /* Initialize support for Trusted Platform Module v1.2 */
171 BlpTpmInitialize();
172#endif
173
174#ifdef BL_TPM_SUPPORT
175 /* Initialize the event manager */
176 EnSubsystemInitialized = 1;
177 InitializeListHead(&EnEventNotificationList);
178#endif
179
180 /* Initialize the I/O Manager */
182 if (!NT_SUCCESS(Status))
183 {
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)
188 {
189 BlpEnDestroy();
190 }
191#endif
192 //BlpMmDestroy(1);
193 return Status;
194 }
195
196#ifdef BL_NET_SUPPORT
197 /* Initialize the network stack */
198 Status = BlNetInitialize();
199 if (!NT_SUCCESS(Status))
200 {
201 /* Destroy the I/O, event, and memory managers in phase 1 */
202 BlpIoDestroy();
203#ifdef BL_TPM_SUPPORT
204 if (EnSubsystemInitialized)
205 {
206 BlpEnDestroy();
207 }
208#endif
209 BlpMmDestroy(1);
210 return Status;
211 }
212#endif
213
214 /* Initialize the utility library */
216 if (!NT_SUCCESS(Status))
217 {
218 /* Destroy the network, I/O, event, and memory managers in phase 1 */
219#ifdef BL_NET_SUPPORT
220 BlNetDestroy();
221#endif
222 //BlpIoDestroy();
223#ifdef BL_TPM_SUPPORT
224 if (EnSubsystemInitialized)
225 {
226 BlpEnDestroy();
227 }
228#endif
229 //BlpMmDestroy(1);
230 EfiPrintf(L"Util init failed\r\n");
231 return Status;
232 }
233
234#ifdef BL_KD_SUPPORT
235 /* Initialize PCI Platform Support */
236 PltInitializePciConfiguration();
237#endif
238
239#ifdef BL_SECURE_BOOT_SUPPORT
240 /* Read the current SecureBoot Policy*/
241 Status = BlSecureBootSetActivePolicyFromPersistedData();
242 if (!NT_SUCCESS(Status))
243 {
244 /* Destroy everything that we've currently set up */
245#ifdef BL_KD_SUPPORT
246 PltDestroyPciConfiguration();
247#endif
248#ifdef BL_NET_SUPPORT
249 BlNetDestroy();
250#endif
251 BlpIoDestroy();
252#ifdef BL_TPM_SUPPORT
253 if (EnSubsystemInitialized)
254 {
255 BlpEnDestroy();
256 }
257#endif
258 BlpMmDestroy(1);
259 return Status;
260 }
261#endif
262
263#ifdef BL_TPM_SUPPORT
264 /* Initialize phase 0 of the security subsystem */
265 SipInitializePhase0();
266#endif
267
268#ifdef BL_KD_SUPPORT
269 /* Bring up the boot debugger, now that SecureBoot has been processed */
270 BlBdInitialize();
271#endif
272
273#ifdef BL_ETW_SUPPORT
274 /* Initialize internal logging */
275 BlpLogInitialize();
276#endif
277
278 /* Are graphics enabled? */
279 if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_NO_DISPLAY))
280 {
281 /* Initialize the graphics library */
282 BlpDisplayInitialize(LibraryParameters->LibraryFlags);
283 }
284
285 /* Initialize the boot application persistent data */
288
289#ifdef BL_TPM_SUPPORT
290 /* Now setup the security subsystem in phase 1 */
291 BlpSiInitialize(1);
292#endif
293
294 /* Setup the text, UI and font resources */
296 if (!NT_SUCCESS(Status))
297 {
298 /* Tear down everything if this failed */
299 if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_NO_DISPLAY))
300 {
301// BlpDisplayDestroy();
302 }
303#ifdef BL_KD_SUPPORT
304 BlpBdDestroy();
305 PltDestroyPciConfiguration();
306#endif
307#ifdef BL_NET_SUPPORT
308 BlNetDestroy();
309#endif
310 //BlpIoDestroy();
311#ifdef BL_TPM_SUPPORT
312 if (EnSubsystemInitialized)
313 {
314 BlpEnDestroy();
315 }
316#endif
317 //BlpMmDestroy(1);
318 return Status;
319 }
320
321#if BL_BITLOCKER_SUPPORT
322 /* Setup the boot cryptography library */
323 g_pEnvironmentData = &SymCryptEnvironmentWindowsBootLibrary;
324 if (SymCryptEnvWindowsBootLibInit)
325 {
326 SymCryptEnvWindowsBootLibInit();
327 }
328#endif
329
330 /* We are fully initialized, remember this and exit with success */
333
334Quickie:
335 return Status;
336}
337
338/*++
339 * @name BlInitializeLibrary
340 *
341 * The BlInitializeLibrary function initializes, or re-initializes, the
342 * Boot Library.
343 *
344 * @param BootParameters
345 * Pointer to the Boot Application Parameter Block.
346 *
347 * @param LibraryParameters
348 * Pointer to the Boot Library Parameters.
349 *
350 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
351 * otherwise.
352 *
353 *--*/
356 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters,
357 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
358 )
359{
361
362 /* Are we re-initializing the library? */
363 if (LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE)
364 {
365 /* From scratch? */
366 BlpLibraryParameters = *LibraryParameters;
367 if (LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE_ALL)
368 {
369#ifdef BL_TPM_SUPPORT
370 /* Reinitialize the TPM security enclave as BCD hash changed */
371 BlpSiInitialize(1);
372#endif
373#ifdef BL_KD_SUPPORT
374 /* Reinitialize the boot debugger as BCD debug options changed */
375 BlBdInitialize();
376#endif
377
378 /* Reparse the bad page list now that the BCD has been reloaded */
380
381 /* Reparse the low/high physical address limits as well */
383
384 /* Redraw the graphics console as needed */
385 BlpDisplayInitialize(LibraryParameters->LibraryFlags);
386
387 /* Reinitialize resources (language may have changed) */
389 }
390
391 /* Nothing to do, we're done */
393 }
394 else
395 {
396 /* Nope, this is first time initialization */
397 Status = InitializeLibrary(BootAppParameters, LibraryParameters);
398 }
399
400 /* Return initialization status */
401 return Status;
402}
403
404VOID
406 VOID
407 )
408{
409 EfiPrintf(L"Destroy not yet implemented\r\n");
410 return;
411}
412
413PGUID
415 VOID
416 )
417{
418 /* Return the GUID, if one was present */
421}
422
425 _Out_ PVOID* ImageBase,
426 _Out_ PULONG ImageSize
427 )
428{
429 /* Fail if output parameters are missing */
430 if (!ImageBase || !ImageSize)
431 {
433 }
434
435 /* Return the requested data */
438 return STATUS_SUCCESS;
439}
440
441VOID
444 )
445{
446 /* Check if we had allocated BCD options */
447 if (AppEntry->Flags & BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL)
448 {
449 BlMmFreeHeap(AppEntry->BcdData);
450 }
451
452 /* Free the entry itself */
453 BlMmFreeHeap(AppEntry);
454}
455
458 _In_ const GUID* DataGuid,
461 )
462{
463 /* Check for invalid or missing parameters */
464 if (!(DataBlob) ||
465 !(DataGuid) ||
466 ((DataBlob->BlobSize) && !(DataBlob->Data)))
467 {
469 }
470
471 /* Check if there's no persistent data blobs */
473 {
474 return STATUS_NOT_FOUND;
475 }
476
477 /* Not yet handled, TODO */
478 EfiPrintf(L"Boot persistent data not yet implemented\r\n");
480}
unsigned char BOOLEAN
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
LONG NTSTATUS
Definition: precomp.h:26
ULONGLONG BlpTimePerformanceFrequency
Definition: time.c:15
struct _BL_FIRMWARE_DESCRIPTOR * PBL_FIRMWARE_DESCRIPTOR
struct _BL_DEVICE_DESCRIPTOR * PBL_DEVICE_DESCRIPTOR
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
NTSTATUS BlpDisplayInitialize(_In_ ULONG Flags)
Definition: display.c:575
#define BOOT_APPLICATION_SIGNATURE_2
Definition: bl.h:56
NTSTATUS BlpTimeCalibratePerformanceCounter(VOID)
Definition: time.c:62
#define BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
Definition: bl.h:131
NTSTATUS BlpIoInitialize(VOID)
Definition: io.c:35
struct _BL_APPLICATION_ENTRY * PBL_APPLICATION_ENTRY
struct _BL_MEMORY_DATA * PBL_MEMORY_DATA
#define BL_LIBRARY_FLAG_REINITIALIZE
Definition: bl.h:128
NTSTATUS BlUtlInitialize(VOID)
Definition: util.c:197
#define BL_APPLICATION_ENTRY_FLAG_NO_GUID
Definition: bl.h:68
NTSTATUS BlMmRemoveBadMemory(VOID)
Definition: mm.c:155
NTSTATUS BlpMmInitialize(_In_ PBL_MEMORY_DATA MemoryData, _In_ BL_TRANSLATION_TYPE TranslationType, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: mm.c:541
NTSTATUS BlpResourceInitialize(VOID)
Definition: resource.c:478
#define BL_LIBRARY_FLAG_REINITIALIZE_ALL
Definition: bl.h:129
#define BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL
Definition: bl.h:69
#define BL_APP_ENTRY_SIGNATURE
Definition: bl.h:53
#define BOOT_APPLICATION_SIGNATURE_1
Definition: bl.h:55
NTSTATUS BlpArchInitialize(_In_ ULONG Phase)
Definition: arch.c:235
NTSTATUS BlpMmInitializeConstraints(VOID)
Definition: pagealloc.c:106
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
NTSTATUS BlpFwInitialize(_In_ ULONG Phase, _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareParameters)
Definition: firmware.c:2290
#define BL_LIBRARY_FLAG_NO_DISPLAY
Definition: bl.h:127
NTSTATUS BlGetBootOptionInteger(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PULONGLONG Value)
Definition: bcdopt.c:467
#define BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL
Definition: bl.h:74
VOID BlDestroyBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry)
Definition: bootlib.c:442
NTSTATUS BlInitializeLibrary(_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bootlib.c:355
PWCHAR BlpApplicationBaseDirectory
Definition: bootlib.c:17
LIST_ENTRY BlpPdListHead
Definition: bootlib.c:24
PBL_DEVICE_DESCRIPTOR BlpBootDevice
Definition: bootlib.c:16
ULONG BlpApplicationFlags
Definition: bootlib.c:21
NTSTATUS BlPdQueryData(_In_ const GUID *DataGuid, _In_ PVOID Unknown, _Inout_ PBL_PD_DATA_BLOB DataBlob)
Definition: bootlib.c:457
PGUID BlGetApplicationIdentifier(VOID)
Definition: bootlib.c:414
BL_LIBRARY_PARAMETERS BlpLibraryParameters
Definition: bootlib.c:15
VOID BlDestroyLibrary(VOID)
Definition: bootlib.c:405
NTSTATUS InitializeLibrary(_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bootlib.c:44
PBOOT_APPLICATION_PARAMETER_BLOCK BlpApplicationParameters
Definition: bootlib.c:18
NTSTATUS BlGetApplicationBaseAndSize(_Out_ PVOID *ImageBase, _Out_ PULONG ImageSize)
Definition: bootlib.c:424
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
BOOLEAN BlpLibraryParametersInitialized
Definition: bootlib.c:20
ULONG PdPersistAllocations
Definition: bootlib.c:23
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ULONG_PTR
Definition: config.h:101
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
Status
Definition: gdiplustypes.h:25
@ Unknown
Definition: i8042prt.h:114
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:483
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
Definition: bl.h:855
ULONG Flags
Definition: bl.h:857
CHAR Signature[8]
Definition: bl.h:856
GUID Guid
Definition: bl.h:858
BL_BCD_OPTION BcdData
Definition: bl.h:860
ULONG LibraryFlags
Definition: bl.h:757
Definition: bl.h:864
ULONG Flags
Definition: bl.h:865
PBL_BCD_OPTION BcdData
Definition: bl.h:867
GUID Guid
Definition: bl.h:866
Definition: typedefs.h:120
uint32_t * PULONG
Definition: typedefs.h:59
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONGLONG QuadPart
Definition: typedefs.h:114