ReactOS  0.4.14-dev-57-g333b8f1
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  *--*/
45  _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters,
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 */
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;
105  BlpApplicationEntry.BcdData = &AppEntry->BcdData;
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 */
144  BlpTimePerformanceFrequency = BootFrequency.QuadPart;
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 
334 Quickie:
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  *--*/
354 NTSTATUS
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 
404 VOID
406  VOID
407  )
408 {
409  EfiPrintf(L"Destroy not yet implemented\r\n");
410  return;
411 }
412 
413 PGUID
415  VOID
416  )
417 {
418  /* Return the GUID, if one was present */
421 }
422 
423 NTSTATUS
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 */
437  *ImageSize = BlpApplicationParameters->ImageSize;
438  return STATUS_SUCCESS;
439 }
440 
441 VOID
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 
456 NTSTATUS
458  _In_ const GUID* DataGuid,
460  _Inout_ PBL_PD_DATA_BLOB DataBlob
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");
479  return STATUS_NOT_IMPLEMENTED;
480 }
ULONG PdPersistAllocations
Definition: bootlib.c:23
#define BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL
Definition: bl.h:70
PBOOT_APPLICATION_PARAMETER_BLOCK BlpApplicationParameters
Definition: bootlib.c:18
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
VOID BlDestroyLibrary(VOID)
Definition: bootlib.c:405
#define BL_LIBRARY_FLAG_REINITIALIZE
Definition: bl.h:129
#define TRUE
Definition: types.h:120
NTSTATUS InitializeLibrary(_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bootlib.c:44
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
ULONGLONG BlpTimePerformanceFrequency
Definition: time.c:15
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
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
GUID Guid
Definition: bl.h:859
LONG NTSTATUS
Definition: precomp.h:26
PGUID BlGetApplicationIdentifier(VOID)
Definition: bootlib.c:414
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:469
#define BOOT_APPLICATION_SIGNATURE_2
Definition: bl.h:57
CHAR Signature[8]
Definition: bl.h:857
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSTATUS BlpTimeCalibratePerformanceCounter(VOID)
Definition: time.c:62
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
struct _BL_FIRMWARE_DESCRIPTOR * PBL_FIRMWARE_DESCRIPTOR
NTSTATUS BlGetBootOptionInteger(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PULONGLONG Value)
Definition: bcdopt.c:467
NTSTATUS BlMmRemoveBadMemory(VOID)
Definition: mm.c:155
#define BL_APP_ENTRY_SIGNATURE
Definition: bl.h:54
NTSTATUS BlInitializeLibrary(_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bootlib.c:355
uint32_t ULONG_PTR
Definition: typedefs.h:63
PWCHAR BlpApplicationBaseDirectory
Definition: bootlib.c:17
Definition: bl.h:855
NTSTATUS BlpMmInitializeConstraints(VOID)
Definition: pagealloc.c:106
BL_LIBRARY_PARAMETERS BlpLibraryParameters
Definition: bootlib.c:15
PBL_BCD_OPTION BcdData
Definition: bl.h:868
ULONG LibraryFlags
Definition: bl.h:758
ULONG BlpApplicationFlags
Definition: bootlib.c:21
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _Out_
Definition: no_sal2.h:323
#define BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
Definition: bl.h:132
Definition: bl.h:864
void * PVOID
Definition: retypes.h:9
LIST_ENTRY BlpPdListHead
Definition: bootlib.c:24
#define STATUS_NOT_FOUND
Definition: shellext.h:67
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS BlUtlInitialize(VOID)
Definition: util.c:197
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
NTSTATUS BlpDisplayInitialize(_In_ ULONG Flags)
Definition: display.c:574
NTSTATUS BlPdQueryData(_In_ const GUID *DataGuid, _In_ PVOID Unknown, _Inout_ PBL_PD_DATA_BLOB DataBlob)
Definition: bootlib.c:457
#define _Inout_
Definition: no_sal2.h:244
NTSTATUS BlGetApplicationBaseAndSize(_Out_ PVOID *ImageBase, _Out_ PULONG ImageSize)
Definition: bootlib.c:424
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:117
VOID BlDestroyBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry)
Definition: bootlib.c:442
ULONG Flags
Definition: bl.h:858
Status
Definition: gdiplustypes.h:24
GUID Guid
Definition: bl.h:867
#define BL_LIBRARY_FLAG_NO_DISPLAY
Definition: bl.h:128
NTSTATUS BlpArchInitialize(_In_ ULONG Phase)
Definition: arch.c:235
struct _BL_DEVICE_DESCRIPTOR * PBL_DEVICE_DESCRIPTOR
#define _In_
Definition: no_sal2.h:204
NTSTATUS BlpFwInitialize(_In_ ULONG Phase, _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareParameters)
Definition: firmware.c:2290
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int * PULONG
Definition: retypes.h:1
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define BL_LIBRARY_FLAG_REINITIALIZE_ALL
Definition: bl.h:130
#define BOOT_APPLICATION_SIGNATURE_1
Definition: bl.h:56
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
ULONG Flags
Definition: bl.h:866
NTSTATUS BlpIoInitialize(VOID)
Definition: io.c:35
unsigned int ULONG
Definition: retypes.h:1
struct _BL_APPLICATION_ENTRY * PBL_APPLICATION_ENTRY
#define ULONG_PTR
Definition: config.h:101
#define BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL
Definition: bl.h:75
BOOLEAN BlpLibraryParametersInitialized
Definition: bootlib.c:20
#define BL_APPLICATION_ENTRY_FLAG_NO_GUID
Definition: bl.h:69
struct _BL_MEMORY_DATA * PBL_MEMORY_DATA
return STATUS_SUCCESS
Definition: btrfs.c:2966
PBL_DEVICE_DESCRIPTOR BlpBootDevice
Definition: bootlib.c:16
LONGLONG QuadPart
Definition: typedefs.h:112
BL_BCD_OPTION BcdData
Definition: bl.h:861