diff options
Diffstat (limited to 'Lessons/Lesson_29')
30 files changed, 1642 insertions, 0 deletions
diff --git a/Lessons/Lesson_29/Conf/target.txt b/Lessons/Lesson_29/Conf/target.txt new file mode 100644 index 0000000..c109dcf --- /dev/null +++ b/Lessons/Lesson_29/Conf/target.txt @@ -0,0 +1,7 @@ +ACTIVE_PLATFORM       = UefiLessonsPkg/UefiLessonsPkg.dsc
 +TARGET                = RELEASE
 +TARGET_ARCH           = X64
 +TOOL_CHAIN_CONF       = Conf/tools_def.txt
 +TOOL_CHAIN_TAG        = GCC5
 +BUILD_RULE_CONF = Conf/build_rule.txt
 +
 diff --git a/Lessons/Lesson_29/README.md b/Lessons/Lesson_29/README.md new file mode 100644 index 0000000..1b613e7 --- /dev/null +++ b/Lessons/Lesson_29/README.md @@ -0,0 +1,427 @@ +In the last lesson we've discovered that our system has BGRT ACPI table. + +According to the ACPI specification: +``` +The Boot Graphics Resource Table (BGRT) is an optional table that provides a mechanism to indicate that +an image was drawn on the screen during boot, and some information about the image. +The table is written when the image is drawn on the screen. This should be done after it is expected that +any firmware components that may write to the screen are done doing so and it is known that the image +is the only thing on the screen. If the boot path is interrupted (e.g., by a key press), the valid bit within the +status field should be changed to 0 to indicate to the OS that the current image is invalidated +``` +This table actually have a pointer to image data, check structure definition under https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/Acpi63.h: +``` +/// +/// Boot Graphics Resource Table definition. +/// +typedef struct { +  EFI_ACPI_DESCRIPTION_HEADER Header; +  /// +  /// 2-bytes (16 bit) version ID. This value must be 1. +  /// +  UINT16                      Version; +  /// +  /// 1-byte status field indicating current status about the table. +  ///     Bits[7:1] = Reserved (must be zero) +  ///     Bit [0] = Valid. A one indicates the boot image graphic is valid. +  /// +  UINT8                       Status; +  /// +  /// 1-byte enumerated type field indicating format of the image. +  ///     0 = Bitmap +  ///     1 - 255  Reserved (for future use) +  /// +  UINT8                       ImageType; +  /// +  /// 8-byte (64 bit) physical address pointing to the firmware's in-memory copy +  /// of the image bitmap. +  /// +  UINT64                      ImageAddress; +  /// +  /// A 4-byte (32-bit) unsigned long describing the display X-offset of the boot image. +  /// (X, Y) display offset of the top left corner of the boot image. +  /// The top left corner of the display is at offset (0, 0). +  /// +  UINT32                      ImageOffsetX; +  /// +  /// A 4-byte (32-bit) unsigned long describing the display Y-offset of the boot image. +  /// (X, Y) display offset of the top left corner of the boot image. +  /// The top left corner of the display is at offset (0, 0). +  /// +  UINT32                      ImageOffsetY; +} EFI_ACPI_6_3_BOOT_GRAPHICS_RESOURCE_TABLE; +``` + + +Let's create an app that would save an image from BGRT. + +This time to get BGRT table we would utilize `EFI_ACPI_SDT_PROTOCOL` protocol. + +To get ACPI table data we would use `GetAcpiTable()` function from this protocol: +``` +EFI_ACPI_SDT_PROTOCOL.GetAcpiTable() + +Summary: +Returns a requested ACPI table. + +Prototype: +typedef +EFI_STATUS +(EFIAPI *EFI_ACPI_GET_ACPI_TABLE) ( + IN UINTN Index, + OUT EFI_ACPI_SDT_HEADER **Table, + OUT EFI_ACPI_TABLE_VERSION *Version, + OUT UINTN *TableKey + ); + +Parameters: +Index		The zero-based index of the table to retrieve. +Table		Pointer for returning the table buffer. +Version		On return, updated with the ACPI versions to which this table belongs. +TableKey	On return, points to the table key for the specified ACPI system definition table. + +Description: +The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated with the Index that was input. The following structures are not considered elements in the list of ACPI tables: +- Root System Description Pointer (RSD_PTR) +- Root System Description Table (RSDT) +- Extended System Description Table (XSDT) +``` +In edk2 it is defined here: https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/AcpiSystemDescriptionTable.h + +To get all tables we need to call `GetAcpiTable` with incrementing values for `Index` starting with 0, while function returns `EFI_SUCCESS`. + +On every success call we would get a pointer to a common header for a ACPI table: +``` +typedef struct { + UINT32 Signature; + UINT32 Length; + UINT8 Revision; + UINT8 Checksum; + CHAR8 OemId[6]; + CHAR8 OemTableId[8]; + UINT32 OemRevision; + UINT32 CreatorId; + UINT32 CreatorRevision; +} EFI_ACPI_SDT_HEADER; +``` + +To use `EFI_ACPI_SDT_PROTOCOL` we need to add include to our file: +``` +#include <Protocol/AcpiSystemDescriptionTable.h> +``` +And add protocol to the *.inf file: +``` +[Protocols] +  gEfiAcpiSdtProtocolGuid +``` + +Here is a code finding BGRT ACPI table: +``` +EFI_ACPI_SDT_PROTOCOL* AcpiSdtProtocol; +EFI_STATUS Status = gBS->LocateProtocol ( +                &gEfiAcpiSdtProtocolGuid, +                NULL, +                (VOID**)&AcpiSdtProtocol +                ); +if (EFI_ERROR (Status)) { +  return Status; +} + +BOOLEAN BGRT_found = FALSE; +UINTN Index = 0; +EFI_ACPI_SDT_HEADER* Table; +EFI_ACPI_TABLE_VERSION Version; +UINTN TableKey; +while (TRUE) { +  Status = AcpiSdtProtocol->GetAcpiTable(Index, +    &Table, +    &Version, +    &TableKey +  ); +  if (EFI_ERROR(Status)) { +    break; +  } +  if (((CHAR8)((Table->Signature >>  0) & 0xFF) == 'B') && +      ((CHAR8)((Table->Signature >>  8) & 0xFF) == 'G') && +      ((CHAR8)((Table->Signature >> 16) & 0xFF) == 'R') && +      ((CHAR8)((Table->Signature >> 24) & 0xFF) == 'T')) { +    BGRT_found = TRUE; +    break; +  } +  Index++; +} +if (!BGRT_found) { +  Print(L"BGRT table is not present in the system\n"); +  return EFI_UNSUPPORTED; +} +``` + +Now we need to save an image from BGRT table. + +Currently ACPI specification support only BMP image type https://uefi.org/specs/ACPI/6.4/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#image-type + +So first we check if the type is actually BMP: +``` +EFI_ACPI_6_3_BOOT_GRAPHICS_RESOURCE_TABLE* BGRT = (EFI_ACPI_6_3_BOOT_GRAPHICS_RESOURCE_TABLE*)Table; +if (BGRT->ImageType == 0) { +  ... +} +``` + +Now we need to actually save a BMP image. BGRT doesn't contain any size for an image, only offset to data: `ImageAddress`. + +To get image size we need to look at BMP header.  + +In edk2 it is defined under https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/Bmp.h: +``` +typedef struct { +  CHAR8         CharB; +  CHAR8         CharM; +  UINT32        Size; +  UINT16        Reserved[2]; +  UINT32        ImageOffset; +  UINT32        HeaderSize; +  UINT32        PixelWidth; +  UINT32        PixelHeight; +  UINT16        Planes;          ///< Must be 1 +  UINT16        BitPerPixel;     ///< 1, 4, 8, or 24 +  UINT32        CompressionType; +  UINT32        ImageSize;       ///< Compressed image size in bytes +  UINT32        XPixelsPerMeter; +  UINT32        YPixelsPerMeter; +  UINT32        NumberOfColors; +  UINT32        ImportantColors; +} BMP_IMAGE_HEADER; +``` + +Don't forget to include this file in our program: +``` +#include <IndustryStandard/Bmp.h> +``` + +When we know that the image is BMP, we can check its signature (`BM`), parse its size and actually write its data to a file. Here we use `EFI_STATUS WriteFile(CHAR16* FileName, VOID* Data, UINTN* Size)` function to write data to a file, we will define it in a minute: +``` +BMP_IMAGE_HEADER* BMP = (BMP_IMAGE_HEADER*)(BGRT->ImageAddress); + +if ((BMP->CharB != 'B') || (BMP->CharM != 'M')) { +  Print(L"BMP image has wrong signature!\n"); +  return EFI_UNSUPPORTED; +} +Print(L"BGRT conatins BMP image with %dx%d resolution\n", BMP->PixelWidth, BMP->PixelHeight); +UINTN Size = BMP->Size; +Status = WriteFile(L"BGRT.bmp", BMP, &Size); +if (EFI_ERROR(Status)) { +  Print(L"Error! Can't write BGRT.bmp file\n"); +} +``` + +Last time we've used `EFI_SHELL_PROTOCOL` to create a file and write data to it. This time we will try to utilize ShelLib: + +https://github.com/tianocore/edk2/blob/master/ShellPkg/Include/Library/ShellLib.h + +https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellLib/UefiShellLib.c + +Again we will need 3 functions: for file open, write and close: +``` +/** +  This function will open a file or directory referenced by filename. +  If return is EFI_SUCCESS, the Filehandle is the opened file's handle; +  otherwise, the Filehandle is NULL. Attributes is valid only for +  EFI_FILE_MODE_CREATE. +  @param[in] FileName           The pointer to file name. +  @param[out] FileHandle        The pointer to the file handle. +  @param[in] OpenMode           The mode to open the file with. +  @param[in] Attributes         The file's file attributes. +  ... +**/ + +EFI_STATUS +EFIAPI +ShellOpenFileByName( +  IN CONST CHAR16               *FileName, +  OUT SHELL_FILE_HANDLE         *FileHandle, +  IN UINT64                     OpenMode, +  IN UINT64                     Attributes +  ); +``` +``` +/** +  Write data to a file. +  This function writes the specified number of bytes to the file at the current +  file position. The current file position is advanced the actual number of bytes +  written, which is returned in BufferSize. Partial writes only occur when there +  has been a data error during the write attempt (such as "volume space full"). +  The file is automatically grown to hold the data if required. Direct writes to +  opened directories are not supported. +  @param[in] FileHandle          The opened file for writing. +  @param[in, out] BufferSize     On input the number of bytes in Buffer.  On output +                                 the number of bytes written. +  @param[in] Buffer              The buffer containing data to write is stored. +  ... +**/ + +EFI_STATUS +EFIAPI +ShellWriteFile( +  IN SHELL_FILE_HANDLE          FileHandle, +  IN OUT UINTN                  *BufferSize, +  IN VOID                       *Buffer +  ); +``` +``` +/** +  Close an open file handle. +  This function closes a specified file handle. All "dirty" cached file data is +  flushed to the device, and the file is closed. In all cases the handle is +  closed. +  @param[in] FileHandle           The file handle to close. +**/ + +EFI_STATUS +EFIAPI +ShellCloseFile ( +  IN SHELL_FILE_HANDLE          *FileHandle +  ); +``` + +Advantage of using `ShellLib` is that now we don't need to find `EFI_SHELL_PROTOCOL` and work with it manually. + + +Our `WriteFile` function would look like this: +``` +EFI_STATUS WriteFile(CHAR16* FileName, VOID* Data, UINTN* Size) +{ +  SHELL_FILE_HANDLE FileHandle; +  EFI_STATUS Status = ShellOpenFileByName( +    FileName, +    &FileHandle, +    EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, +    0 +  ); +  if (!EFI_ERROR(Status)) { +    Print(L"Save it to %s\n", FileName); +    UINTN ToWrite = *Size; +    Status = ShellWriteFile( +      FileHandle, +      Size, +      Data +    ); +    if (EFI_ERROR(Status)) { +      Print(L"Can't write file: %r\n", Status); +    } +    if (*Size != ToWrite) { +      Print(L"Error! Not all data was written\n"); +    } +    Status = ShellCloseFile( +      &FileHandle +    ); +    if (EFI_ERROR(Status)) { +      Print(L"Can't close file: %r\n", Status); +    } +  } else { +    Print(L"Can't open file: %r\n", Status); +  } +  return Status; +} +``` + +To use ShellLib we need to include a header in our program: +``` +#include <Library/ShellLib.h> +``` + +Also we need to add `ShellPkg.dec` to our packages and add `ShellLib` to our library classes: +``` +[Packages] +  MdePkg/MdePkg.dec ++  ShellPkg/ShellPkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib ++  ShellLib +``` +Besides that our package `*.dsc` file needs to include a `ShellLib` library class: +``` +[LibraryClasses] +  ... +  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf +``` + +Unfortunately this is not enough, our current build would fail with a message, because `ShellLib` by itself needs another library: +``` +build.py... +/home/kostr/tiano/edk2/UefiLessonsPkg/UefiLessonsPkg.dsc(...): error 4000: Instance of library class [FileHandleLib] is not found +``` + +To find it use our standard tactic: +``` +$ grep FileHandleLib -r ./ --include=*.inf | grep LIBRARY_CLASS +``` + +In the end we had to add several more LibraryClasses to make our build succeed: +``` +[LibraryClasses] +  ... +  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf +  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf +``` + +Build our app and execute it under OVMF: +``` +FS0:\> SaveBGRT.efi +BGRT conatins BMP image with 193x58 resolution +Save it to BGRT.bmp7 +FS0:\> +``` + +If you look at the BGRT.bmp picture that are app have produced, it would have the same content as https://raw.githubusercontent.com/tianocore/edk2/master/MdeModulePkg/Logo/Logo.bmp + +The file itself wouldn't be the same since BGRT driver don't use an image from flash, but actually grabs a boot screen and transforms it to a BMP image. For the proof checkout how https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.c uses `TranslateGopBltToBmp` function from the https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/BaseBmpSupportLib/BmpSupportLib.c library. +If you find it strange that BGRT grabs a screen instead of using an image from flash, remember how BGRT is defined in ACPI specification: +``` +The Boot Graphics Resource Table (BGRT) is an optional table that provides a mechanism to indicate that an image was drawn on the screen during boot +``` + +The file GUID for binary boot logo image is defined in the file https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Logo/Logo.inf +``` +FILE_GUID                      = 7BB28B99-61BB-11D5-9A5D-0090273FC14D +``` +It is a GUID that is usually used for the Logo image in BIOS. It is even hardcoded to https://github.com/tianocore/edk2/blob/master/BaseTools/Source/Python/Eot/Report.py +``` +## GenerateFfs() method +# +#  Generate FFS information +# +#  @param self: The object pointer +#  @param FfsObj: FFS object after FV image is parsed +# +def GenerateFfs(self, FfsObj): +    self.FfsIndex = self.FfsIndex + 1 +    if FfsObj is not None and FfsObj.Type in [0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xA]: +        FfsGuid = FfsObj.Guid +        FfsOffset = FfsObj._OFF_ +        FfsName = 'Unknown-Module' +        FfsPath = FfsGuid +        FfsType = FfsObj._TypeName[FfsObj.Type] + +        # Hard code for Binary INF +        if FfsGuid.upper() == '7BB28B99-61BB-11D5-9A5D-0090273FC14D': +            FfsName = 'Logo' + +        if FfsGuid.upper() == '7E374E25-8E01-4FEE-87F2-390C23C606CD': +            FfsName = 'AcpiTables' + +        if FfsGuid.upper() == '961578FE-B6B7-44C3-AF35-6BC705CD2B1F': +            FfsName = 'Fat' +        ... +``` + +If you want to know how Logo and BGRT are work in edk2, checkout these drivers: +- https://github.com/tianocore/edk2/tree/master/MdeModulePkg/Library/BootLogoLib/ +- https://github.com/tianocore/edk2/tree/master/MdeModulePkg/Logo/ +- https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/ +- https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/BaseBmpSupportLib/ + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/AcpiInfo/AcpiInfo.c b/Lessons/Lesson_29/UefiLessonsPkg/AcpiInfo/AcpiInfo.c new file mode 100644 index 0000000..0511f59 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/AcpiInfo/AcpiInfo.c @@ -0,0 +1,106 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include <Library/BaseMemoryLib.h> +#include <Protocol/Shell.h> + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  EFI_SHELL_PROTOCOL* ShellProtocol; +  EFI_STATUS Status = gBS->LocateProtocol( +    &gEfiShellProtocolGuid, +    NULL, +    (VOID **)&ShellProtocol +  ); + +  if (EFI_ERROR(Status)) { +    Print(L"Can't open EFI_SHELL_PROTOCOL: %r\n", Status); +    return EFI_SUCCESS; +  } + +  EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER* RSDP = NULL; + +  for (UINTN i=0; i<SystemTable->NumberOfTableEntries; i++) { +    if (CompareGuid(&(SystemTable->ConfigurationTable[i].VendorGuid), &gEfiAcpi20TableGuid)) { +      Print(L"RSDP table is placed at %p\n\n", SystemTable->ConfigurationTable[i].VendorTable); +      RSDP = SystemTable->ConfigurationTable[i].VendorTable; +    } +  } + +  if (!RSDP) { +    Print(L"No ACPI2.0 table was found in the system\n"); +    return EFI_SUCCESS; +  } + +  if (((CHAR8)((RSDP->Signature >>  0) & 0xFF) != 'R') || +      ((CHAR8)((RSDP->Signature >>  8) & 0xFF) != 'S') || +      ((CHAR8)((RSDP->Signature >> 16) & 0xFF) != 'D') || +      ((CHAR8)((RSDP->Signature >> 24) & 0xFF) != ' ') || +      ((CHAR8)((RSDP->Signature >> 32) & 0xFF) != 'P') || +      ((CHAR8)((RSDP->Signature >> 40) & 0xFF) != 'T') || +      ((CHAR8)((RSDP->Signature >> 48) & 0xFF) != 'R') || +      ((CHAR8)((RSDP->Signature >> 56) & 0xFF) != ' ')) { +    Print(L"Error! RSDP signature is not valid!\n"); +    return EFI_SUCCESS; +  } + +  Print(L"System description tables:\n"); +  Print(L"\tRSDT table is placed at address %p\n", RSDP->RsdtAddress); +  Print(L"\tXSDT table is placed at address %p\n", RSDP->XsdtAddress); +  Print(L"\n"); + +  EFI_ACPI_DESCRIPTION_HEADER* XSDT = (EFI_ACPI_DESCRIPTION_HEADER*)RSDP->XsdtAddress; +  if (((CHAR8)((XSDT->Signature >>  0) & 0xFF) != 'X') || +      ((CHAR8)((XSDT->Signature >>  8) & 0xFF) != 'S') || +      ((CHAR8)((XSDT->Signature >> 16) & 0xFF) != 'D') || +      ((CHAR8)((XSDT->Signature >> 24) & 0xFF) != 'T')) { +    Print(L"Error! XSDT signature is not valid!\n"); +    return EFI_SUCCESS; +  } + +  Print(L"Main ACPI tables:\n"); +  UINT64 offset = sizeof(EFI_ACPI_DESCRIPTION_HEADER); +  while (offset < XSDT->Length) { +    UINT64* table_address = (UINT64*)((UINT8*)XSDT + offset); +    EFI_ACPI_6_3_COMMON_HEADER* table = (EFI_ACPI_6_3_COMMON_HEADER*)(*table_address); +    CHAR16 TableName[5]; +    TableName[0] = (CHAR16)((table->Signature>> 0)&0xFF); +    TableName[1] = (CHAR16)((table->Signature>> 8)&0xFF); +    TableName[2] = (CHAR16)((table->Signature>>16)&0xFF); +    TableName[3] = (CHAR16)((table->Signature>>24)&0xFF); +    TableName[4] = 0; + +    Print(L"\t%s table is placed at address %p with length 0x%x\n", +                                             TableName, +                                             table, +                                             table->Length); +    CHAR16 FileName[9] = {0}; +    StrCpyS(FileName, 9, TableName); +    StrCatS(FileName, 9, L".aml"); +    SHELL_FILE_HANDLE FileHandle; +    Status = ShellProtocol->OpenFileByName(FileName, +                                           &FileHandle, +                                           EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ); +    if (!EFI_ERROR(Status)) { +      UINTN size = table->Length; +      Status = ShellProtocol->WriteFile(FileHandle, &size, (VOID*)table); +      if (EFI_ERROR(Status)) { +        Print(L"Error in WriteFile: %r\n", Status); +      } +      Status = ShellProtocol->CloseFile(FileHandle); +      if (EFI_ERROR(Status)) { +        Print(L"Error in CloseFile: %r\n", Status); +      } +    } else { +      Print(L"Error in OpenFileByName: %r\n", Status); +    } +    offset += sizeof(UINT64); +  } + +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/AcpiInfo/AcpiInfo.inf b/Lessons/Lesson_29/UefiLessonsPkg/AcpiInfo/AcpiInfo.inf new file mode 100644 index 0000000..53d0356 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/AcpiInfo/AcpiInfo.inf @@ -0,0 +1,24 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = AcpiInfo +  FILE_GUID                      = 18998798-69a2-4ab5-9ffc-a8ee2494b029 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  AcpiInfo.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib + +[Guids] +  gEfiAcpi20TableGuid + +[Protocols] +  gEfiShellProtocolGuid + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/HelloWorld/HelloWorld.c b/Lessons/Lesson_29/UefiLessonsPkg/HelloWorld/HelloWorld.c new file mode 100644 index 0000000..29a4812 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/HelloWorld/HelloWorld.c @@ -0,0 +1,19 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Hello World!\n"); +  gST->ConOut->OutputString(gST->ConOut, L"Hello again!\n"); +  Print(L"Bye!\n"); + +  UINTN Index; +  gBS->WaitForEvent(1, &(gST->ConIn->WaitForKey), &Index); +  gST->ConIn->Reset(gST->ConIn, FALSE); +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/HelloWorld/HelloWorld.inf b/Lessons/Lesson_29/UefiLessonsPkg/HelloWorld/HelloWorld.inf new file mode 100644 index 0000000..d65ca2e --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/HelloWorld/HelloWorld.inf @@ -0,0 +1,18 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = HelloWorld +  FILE_GUID                      = 2e55fa38-f148-42d3-af90-1be247323e30 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  HelloWorld.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ImageHandle/ImageHandle.c b/Lessons/Lesson_29/UefiLessonsPkg/ImageHandle/ImageHandle.c new file mode 100644 index 0000000..32e9c43 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ImageHandle/ImageHandle.c @@ -0,0 +1,105 @@ +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +typedef struct { +  UINTN               Signature; +  /// All handles list of IHANDLE +  LIST_ENTRY          AllHandles; +  /// List of PROTOCOL_INTERFACE's for this handle +  LIST_ENTRY          Protocols; +  UINTN               LocateRequest; +  /// The Handle Database Key value when this handle was last created or modified +  UINT64              Key; +} IHANDLE; + +typedef struct { +  UINTN               Signature; +  /// Link Entry inserted to mProtocolDatabase +  LIST_ENTRY          AllEntries; +  /// ID of the protocol +  EFI_GUID            ProtocolID; +  /// All protocol interfaces +  LIST_ENTRY          Protocols; +  /// Registerd notification handlers +  LIST_ENTRY          Notify; +} PROTOCOL_ENTRY; + +typedef struct { +  UINTN                       Signature; +  /// Link on IHANDLE.Protocols +  LIST_ENTRY                  Link; +  /// Back pointer +  IHANDLE                     *Handle; +  /// Link on PROTOCOL_ENTRY.Protocols +  LIST_ENTRY                  ByProtocol; +  /// The protocol ID +  PROTOCOL_ENTRY              *Protocol; +  /// The interface value +  VOID                        *Interface; +  /// OPEN_PROTOCOL_DATA list +  LIST_ENTRY                  OpenList; +  UINTN                       OpenListCount; + +} PROTOCOL_INTERFACE; + + +#define offsetof(a,b) ((INTN)(&(((a*)(0))->b))) + +#define container_of(ptr, type, member) ({                      \ +        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \ +        (type *)( (char *)__mptr - offsetof(type,member) );}) + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  IHANDLE* MyHandle = ImageHandle; +  Print(L"Signature: %c %c %c %c\n", (MyHandle->Signature >>  0) & 0xff, +                                     (MyHandle->Signature >>  8) & 0xff, +                                     (MyHandle->Signature >> 16) & 0xff, +                                     (MyHandle->Signature >> 24) & 0xff); + +  Print(L"Back Protocol Interface Link: %p\n", MyHandle->Protocols.BackLink); +  Print(L"Forward Protocol Interface Link: %p\n", MyHandle->Protocols.ForwardLink); + +  LIST_ENTRY *FirstLink = MyHandle->Protocols.ForwardLink; +  LIST_ENTRY *CurrentLink = FirstLink; +  do { +  	PROTOCOL_INTERFACE* MyProtocolInterface = container_of(CurrentLink, PROTOCOL_INTERFACE, Link); + +        Print(L"\n"); +        Print(L"Current Link: %p\n", CurrentLink); +  	Print(L"Signature: %x %x %x %x\n", (MyProtocolInterface->Signature >>  0) & 0xff, +        	                           (MyProtocolInterface->Signature >>  8) & 0xff, +                	                   (MyProtocolInterface->Signature >> 16) & 0xff, +                        	           (MyProtocolInterface->Signature >> 24) & 0xff); + +  	Print(L"Back Link: %p\n", MyProtocolInterface->Link.BackLink); +	Print(L"Forward Link: %p\n", MyProtocolInterface->Link.ForwardLink); +	Print(L"GUID=%g\n", MyProtocolInterface->Protocol->ProtocolID); +        CurrentLink = MyProtocolInterface->Link.ForwardLink; +  } while (CurrentLink != FirstLink); + +  Print(L"________\n"); +  EFI_GUID **ProtocolGuidArray; +  UINTN ArrayCount; +  //EFI_STATUS Status = gBS->ProtocolsPerHandle(NULL,		// Use this to test %r Print formatting option +  EFI_STATUS Status = gBS->ProtocolsPerHandle(ImageHandle, +					      &ProtocolGuidArray, +					      &ArrayCount); + +  if (!EFI_ERROR(Status)) { +    for (int i=0; i<ArrayCount; i++) { +      Print(L"%g\n", ProtocolGuidArray[i]); +    } +    FreePool(ProtocolGuidArray); +  } else { +    Print(L"ProtocolsPerHandle error: %r\n", Status); +  } + +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ImageHandle/ImageHandle.inf b/Lessons/Lesson_29/UefiLessonsPkg/ImageHandle/ImageHandle.inf new file mode 100644 index 0000000..34256ee --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ImageHandle/ImageHandle.inf @@ -0,0 +1,18 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = ImageHandle +  FILE_GUID                      = b68d3472-70c7-4928-841b-6566032e0a23 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  ImageHandle.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ImageInfo/ImageInfo.c b/Lessons/Lesson_29/UefiLessonsPkg/ImageInfo/ImageInfo.c new file mode 100644 index 0000000..c45570e --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ImageInfo/ImageInfo.c @@ -0,0 +1,44 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include <Protocol/LoadedImage.h> +#include <Library/DevicePathLib.h> + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  EFI_STATUS Status; +  EFI_LOADED_IMAGE_PROTOCOL* LoadedImage; + +  Status = gBS->HandleProtocol( +    ImageHandle, +    &gEfiLoadedImageProtocolGuid, +    (VOID **) &LoadedImage +  ); + +  if (Status == EFI_SUCCESS) { +    EFI_DEVICE_PATH_PROTOCOL* DevicePath; + +    Status = gBS->HandleProtocol( +      ImageHandle, +      &gEfiLoadedImageDevicePathProtocolGuid, +      (VOID**) &DevicePath +    ); + +    if (Status == EFI_SUCCESS) { +      Print(L"Image device: %s\n", ConvertDevicePathToText(DevicePath, FALSE, TRUE)); +      Print(L"Image file: %s\n",  ConvertDevicePathToText(LoadedImage->FilePath, FALSE, TRUE));	// EFI_DEVICE_PATH_PROTOCOL *FilePath +      Print(L"Image Base: %X\n", LoadedImage->ImageBase); +      Print(L"Image Size: %X\n", LoadedImage->ImageSize); +    } else { +      Print(L"Can't get EFI_LOADED_IMAGE_PROTOCOL, Status=%r\n", Status); +    } +  } else { +    Print(L"Can't get EFI_DEVICE_PATH_PROTOCOL, Status=%r\n", Status); +  } +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ImageInfo/ImageInfo.inf b/Lessons/Lesson_29/UefiLessonsPkg/ImageInfo/ImageInfo.inf new file mode 100644 index 0000000..0ce54a6 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ImageInfo/ImageInfo.inf @@ -0,0 +1,22 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = ImageInfo +  FILE_GUID                      = b68d3472-70c7-4928-841b-6566032e0a23 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  ImageInfo.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib + +[Protocols] +  gEfiLoadedImageProtocolGuid +  gEfiLoadedImageDevicePathProtocolGuid + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/InteractiveApp/InteractiveApp.c b/Lessons/Lesson_29/UefiLessonsPkg/InteractiveApp/InteractiveApp.c new file mode 100644 index 0000000..59c89a9 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/InteractiveApp/InteractiveApp.c @@ -0,0 +1,34 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  UINTN Index; +  EFI_INPUT_KEY Key; + +  Print(L"Try to guess the secret symbol!\n"); +  Print(L"To quit press 'q'\n"); + +  while(TRUE) { +    gBS->WaitForEvent(1, &(gST->ConIn->WaitForKey), &Index); +    gST->ConIn->ReadKeyStroke(gST->ConIn, &Key); +    Print(L"ScanCode = %04x, UnicodeChar = %04x (%c)\n", Key.ScanCode, Key.UnicodeChar, Key.UnicodeChar); + +    if (Key.UnicodeChar == 'k') { +      Print(L"Correct!\n"); +      break; +    } else if (Key.UnicodeChar == 'q') { +      Print(L"Bye!\n"); +      break; +    } else { +      Print(L"Wrong!\n"); +    } +  } +  gST->ConIn->Reset(gST->ConIn, FALSE); +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/InteractiveApp/InteractiveApp.inf b/Lessons/Lesson_29/UefiLessonsPkg/InteractiveApp/InteractiveApp.inf new file mode 100644 index 0000000..700b779 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/InteractiveApp/InteractiveApp.inf @@ -0,0 +1,18 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = InteractiveApp +  FILE_GUID                      = 1539451b-f300-41fa-a565-dde69c1bed66 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  InteractiveApp.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ListVariables/ListVariables.c b/Lessons/Lesson_29/UefiLessonsPkg/ListVariables/ListVariables.c new file mode 100644 index 0000000..1f3ef4a --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ListVariables/ListVariables.c @@ -0,0 +1,46 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + + +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> + +INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv) +{ +  EFI_GUID VendorGuid; +  UINTN VariableNameSize = sizeof (CHAR16); +  CHAR16* VariableName = AllocateZeroPool(sizeof(CHAR16)); +  if (VariableName == NULL) { +    Print(L"Error on AllocateZeroPool call\n"); +    return EFI_OUT_OF_RESOURCES; +  } + +  while (TRUE) +  { +    UINTN VariableNameSizeOld = VariableNameSize; +    EFI_STATUS Status = gRT->GetNextVariableName(&VariableNameSize, VariableName, &VendorGuid); +    if (Status == EFI_SUCCESS) { +      Print(L"%g: %s\n", VendorGuid, VariableName); +    } else if (Status == EFI_BUFFER_TOO_SMALL) { +      VariableName = ReallocatePool(VariableNameSizeOld, VariableNameSize, VariableName); +      if (VariableName == NULL) { +        Print(L"Error on ReallocatePool call\n"); +        return EFI_OUT_OF_RESOURCES; +      } +      Status = gRT->GetNextVariableName(&VariableNameSize, VariableName, &VendorGuid); +      if (Status == EFI_SUCCESS) { +        Print(L"%g: %s\n", VendorGuid, VariableName); +      } else { +        Print(L"Error on 'gRT->GetNextVariableName' call: %s\n", Status); +        return Status; +      } +    } else if (Status == EFI_NOT_FOUND) { +      FreePool(VariableName); +      return EFI_SUCCESS; +    } else { +      Print(L"Error on 'gRT->GetNextVariableName' call: %s\n", Status); +      return Status; +    } +  } +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ListVariables/ListVariables.inf b/Lessons/Lesson_29/UefiLessonsPkg/ListVariables/ListVariables.inf new file mode 100644 index 0000000..14e9fa2 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ListVariables/ListVariables.inf @@ -0,0 +1,19 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = ListVariables +  FILE_GUID                      = d66f68b2-3591-45af-bf5d-519152b9d877 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = ShellCEntryLib + +[Sources] +  ListVariables.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib +  ShellCEntryLib + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/MemoryInfo/MemoryInfo.c b/Lessons/Lesson_29/UefiLessonsPkg/MemoryInfo/MemoryInfo.c new file mode 100644 index 0000000..8c3bcf2 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/MemoryInfo/MemoryInfo.c @@ -0,0 +1,215 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +// for SetMem +#include <Library/BaseMemoryLib.h> + +#include <Protocol/ShellParameters.h>  + +const CHAR16 *memory_types[] = {  +    L"EfiReservedMemoryType",  +    L"EfiLoaderCode",  +    L"EfiLoaderData",  +    L"EfiBootServicesCode",  +    L"EfiBootServicesData",  +    L"EfiRuntimeServicesCode",  +    L"EfiRuntimeServicesData",  +    L"EfiConventionalMemory",  +    L"EfiUnusableMemory",  +    L"EfiACPIReclaimMemory",  +    L"EfiACPIMemoryNVS",  +    L"EfiMemoryMappedIO",  +    L"EfiMemoryMappedIOPortSpace",  +    L"EfiPalCode", +    L"EfiPersistentMemory", +    L"EfiMaxMemoryType" +}; + + +const CHAR16 *memory_types_OS_view[] = {  +    L"reserved", // L"EfiReservedMemoryType",  +    L"usable",   // L"EfiLoaderCode",  +    L"usable",   // L"EfiLoaderData",  +    L"usable",   // L"EfiBootServicesCode",  +    L"usable",   // L"EfiBootServicesData",  +    L"reserved", // L"EfiRuntimeServicesCode",  +    L"reserved", // L"EfiRuntimeServicesData",  +    L"usable",   // L"EfiConventionalMemory",  +    L"reserved", // L"EfiUnusableMemory",  +    L"ACPI data",// L"EfiACPIReclaimMemory",  +    L"ACPI NVS", // L"EfiACPIMemoryNVS",  +    L"reserved", // L"EfiMemoryMappedIO",  +    L"reserved", // L"EfiMemoryMappedIOPortSpace",  +    L"reserved", // L"EfiPalCode", +    L"usable",   // L"EfiPersistentMemory", +    L"usable",   // L"EfiMaxMemoryType" +}; + + +const CHAR16 *  +memory_type_to_str(UINT32 type)  +{  +    if (type > sizeof(memory_types)/sizeof(CHAR16 *))  +        return L"Unknown";  + +    return memory_types[type];  +} + +const CHAR16 * +memory_type_to_str_OS_view(UINT32 type) +{ +    if (type > sizeof(memory_types_OS_view)/sizeof(CHAR16 *))  +        return L"Unknown";  + +    return memory_types_OS_view[type];  +} + +#define ATTRIBUTE_STR_SIZE 50 + +#define CHECK_EFI_MEMORY_ATTRIBUTE(attr) if (attrs & EFI_MEMORY_##attr) { \ +                                           StrCpyS(&str[i], ATTRIBUTE_STR_SIZE, L" "#attr); \ +                                           i+=StrLen(L" "#attr); \ +                                         } + +const CHAR16 * +memory_attrs_to_str(CHAR16* str, UINT64 attrs) +{ +  int i=0; +  SetMem((VOID *)str, sizeof(str), 0); + +  CHECK_EFI_MEMORY_ATTRIBUTE(UC) +  CHECK_EFI_MEMORY_ATTRIBUTE(WC) +  CHECK_EFI_MEMORY_ATTRIBUTE(WT) +  CHECK_EFI_MEMORY_ATTRIBUTE(WB) +  CHECK_EFI_MEMORY_ATTRIBUTE(UCE) +  CHECK_EFI_MEMORY_ATTRIBUTE(WP) +  CHECK_EFI_MEMORY_ATTRIBUTE(RP) +  CHECK_EFI_MEMORY_ATTRIBUTE(XP) +  CHECK_EFI_MEMORY_ATTRIBUTE(NV) +  CHECK_EFI_MEMORY_ATTRIBUTE(MORE_RELIABLE) +  CHECK_EFI_MEMORY_ATTRIBUTE(RO) +  CHECK_EFI_MEMORY_ATTRIBUTE(SP) +  CHECK_EFI_MEMORY_ATTRIBUTE(CPU_CRYPTO) +  CHECK_EFI_MEMORY_ATTRIBUTE(RUNTIME) + +  return str; +} + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  UINTN MemoryMapSize = 0; +  EFI_MEMORY_DESCRIPTOR* MemoryMap = NULL; +  UINTN MapKey; +  UINTN DescriptorSize; +  UINT32 DescriptorVersion; + +  EFI_STATUS Status; + + +  EFI_SHELL_PARAMETERS_PROTOCOL* ShellParameters; + +  Status = gBS->HandleProtocol( +    ImageHandle, +    &gEfiShellParametersProtocolGuid, +    (VOID **) &ShellParameters +  ); + +  BOOLEAN full=FALSE; +  if (Status == EFI_SUCCESS) { +    if (ShellParameters->Argc == 2) { +      if (!StrCmp(ShellParameters->Argv[1], L"full")) { +        full=TRUE; +      } +    } +  } + + +  Status = gBS->GetMemoryMap( +        &MemoryMapSize, +        MemoryMap, +        &MapKey, +        &DescriptorSize, +        &DescriptorVersion +  ); + +  if (Status == EFI_BUFFER_TOO_SMALL) { +    Status = gBS->AllocatePool( +          EfiBootServicesData, +          MemoryMapSize, +          (void**)&MemoryMap +    ); + +    if (EFI_ERROR(Status)) { +      Print(L"AllocatePool error: %r\n", Status); +      return Status; +    } + +    Status = gBS->GetMemoryMap( +          &MemoryMapSize, +          MemoryMap, +          &MapKey, +          &DescriptorSize, +          &DescriptorVersion +    ); + +    if (!EFI_ERROR(Status)) +    { +      EFI_MEMORY_DESCRIPTOR* desc = MemoryMap; +      EFI_MEMORY_DESCRIPTOR* next_desc; +      int i = 0; +      while ((UINT8 *)desc < (UINT8 *)MemoryMap + MemoryMapSize) { +        UINTN PAGE_SIZE = 4096; +        UINTN mapping_size =(UINTN) desc->NumberOfPages * PAGE_SIZE; + +        UINT64 Start = desc->PhysicalStart; + +        next_desc = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)desc + DescriptorSize); +        if (!full) { +	  while ((UINT8 *)next_desc < (UINT8 *)MemoryMap + MemoryMapSize) { +	    mapping_size =(UINTN) desc->NumberOfPages * PAGE_SIZE; +	    if ((desc->PhysicalStart + mapping_size) == (next_desc->PhysicalStart)) { + +              if (desc->Type != next_desc->Type) { +                if (StrCmp(memory_type_to_str_OS_view(desc->Type),  +                           memory_type_to_str_OS_view(next_desc->Type))) +                  break; +                } + +                desc=next_desc; +	        next_desc = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)next_desc + DescriptorSize); +	    } else { +	        break; +	    } +	  } +        } + +        if (full) { +          CHAR16 str[ATTRIBUTE_STR_SIZE]; +          Print(L"[#%02d] Type: %s  Attr: %s\n", i++,  +            memory_type_to_str(desc->Type), memory_attrs_to_str(str, desc->Attribute)); +          Print(L"      Phys: %016llx-%016llx\n", Start, Start + mapping_size - 1); +        } +        else { +          Print(L" [mem: %016llx-%016llx] %s\n", Start, desc->PhysicalStart + mapping_size - 1, +            memory_type_to_str_OS_view(desc->Type) ); +        } + +        desc = next_desc; +      } + +      gBS->FreePool(MemoryMap); +    } else { +      Print(L"GetMemoryMap with buffer error: %r\n", Status); +    } +  } else { +    Print(L"GetMemoryMap without buffer error: %r\n", Status); +  } + +  return Status; +} + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/MemoryInfo/MemoryInfo.inf b/Lessons/Lesson_29/UefiLessonsPkg/MemoryInfo/MemoryInfo.inf new file mode 100644 index 0000000..777010d --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/MemoryInfo/MemoryInfo.inf @@ -0,0 +1,21 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = MemoryInfo +  FILE_GUID                      = d2ce1d65-603e-4b48-b3e1-fe65d5d0bca8 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  MemoryInfo.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib + +[Protocols] +  gEfiShellParametersProtocolGuid + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/PCDLesson/PCDLesson.c b/Lessons/Lesson_29/UefiLessonsPkg/PCDLesson/PCDLesson.c new file mode 100644 index 0000000..9e0aae0 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/PCDLesson/PCDLesson.c @@ -0,0 +1,43 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include <Library/PcdLib.h> + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  Print(L"PcdMyVar32=%d\n", FixedPcdGet32(PcdMyVar32)); +  Print(L"PcdMyVar32_1=%d\n", FixedPcdGet32(PcdMyVar32_1)); +  Print(L"PcdMyVar32_2=%d\n", FixedPcdGet32(PcdMyVar32_2)); + +  Print(L"PcdMyVar32=%d\n", PcdGet32(PcdMyVar32)); + +  Print(L"PcdMyPatchableVar32=0x%x\n", PcdGet32(PcdMyPatchableVar32)); +  RETURN_STATUS PcdStatus = PcdSet32S(PcdMyPatchableVar32, 44); +  Print(L"PcdStatus=%r\n", PcdStatus); +  Print(L"PcdMyPatchableVar32=%d\n", PcdGet32(PcdMyPatchableVar32)); +  PatchPcdSet32(PcdMyPatchableVar32, 45); +  Print(L"PcdMyPatchableVar32=%d\n", PatchPcdGet32(PcdMyPatchableVar32)); + + +  Print(L"PcdMyFeatureFlagVar=%d\n", FeaturePcdGet(PcdMyFeatureFlagVar)); +  Print(L"PcdMyFeatureFlagVar=%d\n", PcdGetBool(PcdMyFeatureFlagVar)); +  Print(L"PcdMyVarBool=%d\n", FixedPcdGetBool(PcdMyVarBool)); +  Print(L"PcdMyVarBool=%d\n", PcdGetBool(PcdMyVarBool)); +   + + + +  Print(L"PcdMyDynamicExVar32=%x\n", PcdGet32(PcdMyDynamicExVar32)); +  PcdSet32S(PcdMyDynamicExVar32, 52); +  Print(L"PcdMyDynamicExVar32=%x\n", PcdGet32(PcdMyDynamicExVar32)); + +  Print(L"PcdMyDynamicVar32=%x\n", PcdGet32(PcdMyDynamicVar32)); +  PcdSet32S(PcdMyDynamicVar32, 52); +  Print(L"PcdMyDynamicVar32=%x\n", PcdGet32(PcdMyDynamicVar32)); +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/PCDLesson/PCDLesson.inf b/Lessons/Lesson_29/UefiLessonsPkg/PCDLesson/PCDLesson.inf new file mode 100644 index 0000000..cfd39d2 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/PCDLesson/PCDLesson.inf @@ -0,0 +1,39 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = PCDLesson +  FILE_GUID                      = 8c1a6b71-0c4b-4497-aaad-07404edf142c +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  PCDLesson.c + +[Packages] +  MdePkg/MdePkg.dec +  UefiLessonsPkg/UefiLessonsPkg.dec   + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib + +[FixedPcd] +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32  +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_1|43  +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_2|43  +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVarBool  + +[PatchPcd] +  gUefiLessonsPkgTokenSpaceGuid.PcdMyPatchableVar32  + +[FeaturePcd] +  gUefiLessonsPkgTokenSpaceGuid.PcdMyFeatureFlagVar + +[Pcd] +  gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicVar32 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicVar32_1 + +[PcdEx] +  gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicExVar32 + + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/SaveBGRT/SaveBGRT.c b/Lessons/Lesson_29/UefiLessonsPkg/SaveBGRT/SaveBGRT.c new file mode 100644 index 0000000..2fda8d8 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/SaveBGRT/SaveBGRT.c @@ -0,0 +1,104 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include <Protocol/AcpiSystemDescriptionTable.h> +#include <Library/ShellLib.h> +#include <IndustryStandard/Bmp.h> + +EFI_STATUS WriteFile(CHAR16* FileName, VOID* Data, UINTN* Size) +{ +  SHELL_FILE_HANDLE FileHandle; +  EFI_STATUS Status = ShellOpenFileByName( +    FileName, +    &FileHandle, +    EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, +    0 +  ); +  if (!EFI_ERROR(Status)) { +    Print(L"Save it to %s\n", FileName); +    UINTN ToWrite = *Size; +    Status = ShellWriteFile( +      FileHandle, +      Size, +      Data +    ); +    if (EFI_ERROR(Status)) { +      Print(L"Can't write file: %r\n", Status); +    } +    if (*Size != ToWrite) { +      Print(L"Error! Not all data was written\n"); +    } +    Status = ShellCloseFile( +      &FileHandle +    ); +    if (EFI_ERROR(Status)) { +      Print(L"Can't close file: %r\n", Status); +    } +  } else { +    Print(L"Can't open file: %r\n", Status); +  } +  return Status; +} + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  EFI_ACPI_SDT_PROTOCOL* AcpiSdtProtocol; +  EFI_STATUS Status = gBS->LocateProtocol ( +                  &gEfiAcpiSdtProtocolGuid, +                  NULL, +                  (VOID**)&AcpiSdtProtocol +                  ); +  if (EFI_ERROR (Status)) { +    return Status; +  } + +  BOOLEAN BGRT_found = FALSE; +  UINTN Index = 0; +  EFI_ACPI_SDT_HEADER* Table; +  EFI_ACPI_TABLE_VERSION Version; +  UINTN TableKey; +  while (TRUE) { +    Status = AcpiSdtProtocol->GetAcpiTable(Index, +      &Table, +      &Version, +      &TableKey +    ); +    if (EFI_ERROR(Status)) { +      break; +    } +    if (((CHAR8)((Table->Signature >>  0) & 0xFF) == 'B') && +        ((CHAR8)((Table->Signature >>  8) & 0xFF) == 'G') && +        ((CHAR8)((Table->Signature >> 16) & 0xFF) == 'R') && +        ((CHAR8)((Table->Signature >> 24) & 0xFF) == 'T')) { +      BGRT_found = TRUE; +      break; +    } +    Index++; +  } +  if (!BGRT_found) { +    Print(L"BGRT table is not present in the system\n"); +    return EFI_UNSUPPORTED; +  } + +  EFI_ACPI_6_3_BOOT_GRAPHICS_RESOURCE_TABLE* BGRT = (EFI_ACPI_6_3_BOOT_GRAPHICS_RESOURCE_TABLE*)Table; +  if (BGRT->ImageType == 0) { +    BMP_IMAGE_HEADER* BMP = (BMP_IMAGE_HEADER*)(BGRT->ImageAddress); + +    if ((BMP->CharB != 'B') || (BMP->CharM != 'M')) { +      Print(L"BMP image has wrong signature!\n"); +      return EFI_UNSUPPORTED; +    } +    Print(L"BGRT conatins BMP image with %dx%d resolution\n", BMP->PixelWidth, BMP->PixelHeight); +    UINTN Size = BMP->Size; +    Status = WriteFile(L"BGRT.bmp", BMP, &Size); +    if (EFI_ERROR(Status)) { +      Print(L"Error! Can't write BGRT.bmp file\n"); +    } +  } +  return Status; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/SaveBGRT/SaveBGRT.inf b/Lessons/Lesson_29/UefiLessonsPkg/SaveBGRT/SaveBGRT.inf new file mode 100644 index 0000000..93ab1b9 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/SaveBGRT/SaveBGRT.inf @@ -0,0 +1,23 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = SaveBGRT +  FILE_GUID                      = efe33e23-b17c-42b2-9551-87546f215935 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  SaveBGRT.c + +[Packages] +  MdePkg/MdePkg.dec +  ShellPkg/ShellPkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib +  ShellLib + +[Protocols] +  gEfiAcpiSdtProtocolGuid + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ShowBootVariables/ShowBootVariables.c b/Lessons/Lesson_29/UefiLessonsPkg/ShowBootVariables/ShowBootVariables.c new file mode 100644 index 0000000..7f6b58c --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ShowBootVariables/ShowBootVariables.c @@ -0,0 +1,93 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> + +#include <Library/DevicePathLib.h> +#include <Library/PrintLib.h> + + +EFI_STATUS +GetNvramVariable( CHAR16   *VariableName, +                  EFI_GUID *VariableOwnerGuid,  +                  VOID     **Buffer, +                  UINTN    *BufferSize) +{ +    UINTN Size = 0; +    *BufferSize = 0; + +    EFI_STATUS Status = gRT->GetVariable(VariableName, VariableOwnerGuid, NULL, &Size, NULL); +    if (Status != EFI_BUFFER_TOO_SMALL) { +        Print(L"Error! 'gRT->GetVariable' call returned %r\n", Status); +        return Status; +    } + +    *Buffer = AllocateZeroPool(Size); +    if (!Buffer) { +        Print(L"Error! 'AllocateZeroPool' call returned %r\n", Status); +        return EFI_OUT_OF_RESOURCES; +    } + +    Status = gRT->GetVariable(VariableName, VariableOwnerGuid, NULL, &Size, *Buffer); +    if (Status == EFI_SUCCESS) { +        *BufferSize = Size; +    } else { +        FreePool( *Buffer ); +        *Buffer = NULL; +    } + +    return Status; +} + + +VOID PrintBootOption(CHAR16* BootOptionName) +{ +  UINTN OptionSize; +  UINT8* Buffer; +  +  EFI_STATUS Status = GetNvramVariable(BootOptionName, &gEfiGlobalVariableGuid, (VOID**)&Buffer, &OptionSize); +  if (Status == EFI_SUCCESS) { +      EFI_LOAD_OPTION* LoadOption = (EFI_LOAD_OPTION*) Buffer; +      CHAR16* Description = (CHAR16*)(Buffer + sizeof (EFI_LOAD_OPTION)); +      UINTN DescriptionSize = StrSize(Description); + +      Print(L"%s\n", Description); +      if (LoadOption->FilePathListLength != 0) { +        VOID* FilePathList = (UINT8 *)Description + DescriptionSize; +        CHAR16* DevPathString = ConvertDevicePathToText(FilePathList, TRUE, FALSE); +        Print(L"%s\n", DevPathString); +      } +  } else { +    Print(L"Can't get %s variable\n", BootOptionName); +  } +} + + +INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv) +{ +  UINTN OptionSize; +  EFI_STATUS Status; + +  UINT16* BootCurrent; +  Status = GetNvramVariable(L"BootCurrent", &gEfiGlobalVariableGuid, (VOID**)&BootCurrent, &OptionSize); +  if (Status != EFI_SUCCESS) { +    Print(L"Can't get BootCurrent variable\n"); +  } + +  UINT16* BootOrderArray; +  Status = GetNvramVariable(L"BootOrder", &gEfiGlobalVariableGuid, (VOID**)&BootOrderArray, &OptionSize); +  if (Status == EFI_SUCCESS) { +    for (UINTN i=0; i<(OptionSize/sizeof(UINT16)); i++) { +      CHAR16 BootOptionStr[sizeof("Boot####")+1]; +      UnicodeSPrint(BootOptionStr, (sizeof("Boot####")+1)*sizeof(CHAR16), L"Boot%04x", BootOrderArray[i]); +      Print(L"%s%s\n", BootOptionStr, (BootOrderArray[i] == *BootCurrent)? L"*" : L"" ); +      PrintBootOption(BootOptionStr); +      Print(L"\n"); +    } +  } else { +    Print(L"Can't get BootOrder variable\n"); +  } + +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ShowBootVariables/ShowBootVariables.inf b/Lessons/Lesson_29/UefiLessonsPkg/ShowBootVariables/ShowBootVariables.inf new file mode 100644 index 0000000..d2cfba9 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ShowBootVariables/ShowBootVariables.inf @@ -0,0 +1,19 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = ShowBootVariables +  FILE_GUID                      = 31266d12-9c60-478e-905e-05d117a3a9df +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = ShellCEntryLib + +[Sources] +  ShowBootVariables.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib +  ShellCEntryLib + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ShowTables/ShowTables.c b/Lessons/Lesson_29/UefiLessonsPkg/ShowTables/ShowTables.c new file mode 100644 index 0000000..aa32f41 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ShowTables/ShowTables.c @@ -0,0 +1,16 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  for (UINTN i=0; i<SystemTable->NumberOfTableEntries; i++) { +    Print(L"%g, %p\n", SystemTable->ConfigurationTable[i].VendorGuid, +                       SystemTable->ConfigurationTable[i].VendorTable); +  } +  return EFI_SUCCESS; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/ShowTables/ShowTables.inf b/Lessons/Lesson_29/UefiLessonsPkg/ShowTables/ShowTables.inf new file mode 100644 index 0000000..056b823 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/ShowTables/ShowTables.inf @@ -0,0 +1,18 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = ShowTables +  FILE_GUID                      = e249532c-d41a-4bd9-a4a8-7fc143e703f2 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  ShowTables.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/SimpleShellApp/SimpleShellApp.c b/Lessons/Lesson_29/UefiLessonsPkg/SimpleShellApp/SimpleShellApp.c new file mode 100644 index 0000000..b13aa6c --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/SimpleShellApp/SimpleShellApp.c @@ -0,0 +1,14 @@ +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv) +{ +//  SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Hello World!\n"); +  gST->ConOut->OutputString(gST->ConOut, L"Hello again!\n"); +  Print(L"Bye!\n"); + +  for (UINTN i=Argc; i>0; i--) { +    Print(L"Arg[%d]=%s\n", Argc-i, Argv[Argc-i]); +  } +  return 0; +} diff --git a/Lessons/Lesson_29/UefiLessonsPkg/SimpleShellApp/SimpleShellApp.inf b/Lessons/Lesson_29/UefiLessonsPkg/SimpleShellApp/SimpleShellApp.inf new file mode 100644 index 0000000..013bf4e --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/SimpleShellApp/SimpleShellApp.inf @@ -0,0 +1,19 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = SimpleShellApp +  FILE_GUID                      = 2afd1202-545e-4f8d-b8fb-bc179e84ddc8 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = ShellCEntryLib + +[Sources] +  SimpleShellApp.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint +  UefiLib +  ShellCEntryLib + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/SimplestApp/SimplestApp.c b/Lessons/Lesson_29/UefiLessonsPkg/SimplestApp/SimplestApp.c new file mode 100644 index 0000000..8bdf500 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/SimplestApp/SimplestApp.c @@ -0,0 +1,10 @@ +EFI_STATUS +EFIAPI +UefiMain ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  return EFI_SUCCESS; +} + diff --git a/Lessons/Lesson_29/UefiLessonsPkg/SimplestApp/SimplestApp.inf b/Lessons/Lesson_29/UefiLessonsPkg/SimplestApp/SimplestApp.inf new file mode 100644 index 0000000..7d4bae2 --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/SimplestApp/SimplestApp.inf @@ -0,0 +1,16 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = SimplestApp +  FILE_GUID                      = 4a298956-fbe0-47fb-ae3a-2d5a0a959a26 +  MODULE_TYPE                    = UEFI_APPLICATION +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = UefiMain + +[Sources] +  SimplestApp.c + +[Packages] +  MdePkg/MdePkg.dec + +[LibraryClasses] +  UefiApplicationEntryPoint diff --git a/Lessons/Lesson_29/UefiLessonsPkg/UefiLessonsPkg.dec b/Lessons/Lesson_29/UefiLessonsPkg/UefiLessonsPkg.dec new file mode 100644 index 0000000..38048bc --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/UefiLessonsPkg.dec @@ -0,0 +1,35 @@ +[Defines]
 +  DEC_SPECIFICATION              = 0x00010005
 +  PACKAGE_NAME                   = UefiLessonsPkg
 +  PACKAGE_GUID                   = 7e7edbba-ca2c-4177-a3f0-d3371358773a
 +  PACKAGE_VERSION                = 1.01
 +
 +[Includes]
 +
 +[LibraryClasses]
 +
 +[Guids]
 +  # FILE_GUID as defined in UefiLessonsPkg/HelloWorld/HelloWorld.inf
 +  gHelloWorldFileGuid            = {0x2e55fa38, 0xf148, 0x42d3, {0xaf, 0x90, 0x1b, 0xe2, 0x47, 0x32, 0x3e, 0x30}}
 +  gUefiLessonsPkgTokenSpaceGuid = {0x150cab53, 0xad47, 0x4385, {0xb5, 0xdd, 0xbc, 0xfc, 0x76, 0xba, 0xca, 0xf0}}
 +
 +[Protocols]
 +
 +[PcdsFixedAtBuild]
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32|42|UINT32|0x00000001
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_1|42|UINT32|0x00000002
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_2|42|UINT32|0x00000003
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVarBool|FALSE|BOOLEAN|0x00000004
 +
 +[PcdsPatchableInModule]
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyPatchableVar32|0x31313131|UINT32|0x10000001
 +
 +[PcdsFeatureFlag]
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyFeatureFlagVar|FALSE|BOOLEAN|0x20000001
 +
 +[PcdsDynamic]
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicVar32|0x38323232|UINT32|0x30000001
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicVar32_1|42|UINT32|0x30000002
 +
 +[PcdsDynamicEx]
 +  gUefiLessonsPkgTokenSpaceGuid.PcdMyDynamicExVar32|0x38333333|UINT32|0x40000001
 diff --git a/Lessons/Lesson_29/UefiLessonsPkg/UefiLessonsPkg.dsc b/Lessons/Lesson_29/UefiLessonsPkg/UefiLessonsPkg.dsc new file mode 100644 index 0000000..5939fcc --- /dev/null +++ b/Lessons/Lesson_29/UefiLessonsPkg/UefiLessonsPkg.dsc @@ -0,0 +1,50 @@ +[Defines] +  DSC_SPECIFICATION              = 0x0001001C +  PLATFORM_GUID                  = 3db7270f-ffac-4139-90a4-0ae68f3f8167 +  PLATFORM_VERSION               = 0.01 +  PLATFORM_NAME                  = UefiLessonsPkg +  SKUID_IDENTIFIER               = DEFAULT +  SUPPORTED_ARCHITECTURES        = X64 +  BUILD_TARGETS                  = RELEASE + + +[LibraryClasses] +  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf +  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf +  DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf +  #PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf +  RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf +  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf +  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf +  ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf +  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf +  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf   +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf +  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + +[Components] +  UefiLessonsPkg/SimplestApp/SimplestApp.inf +  UefiLessonsPkg/HelloWorld/HelloWorld.inf +  UefiLessonsPkg/ImageHandle/ImageHandle.inf +  UefiLessonsPkg/ImageInfo/ImageInfo.inf +  UefiLessonsPkg/MemoryInfo/MemoryInfo.inf +  UefiLessonsPkg/SimpleShellApp/SimpleShellApp.inf +  UefiLessonsPkg/ListVariables/ListVariables.inf +  UefiLessonsPkg/ShowBootVariables/ShowBootVariables.inf +  UefiLessonsPkg/InteractiveApp/InteractiveApp.inf +  UefiLessonsPkg/PCDLesson/PCDLesson.inf +  UefiLessonsPkg/ShowTables/ShowTables.inf +  UefiLessonsPkg/AcpiInfo/AcpiInfo.inf +  UefiLessonsPkg/SaveBGRT/SaveBGRT.inf + +[PcdsFixedAtBuild] +  gUefiLessonsPkgTokenSpaceGuid.PcdMyVar32_2|44 +  | 
