Beispiel #1
0
/**
  List out help information on all the commands or print extended information
  about a specific passed in command.

  Argv[0] - "help"
  Argv[1] - Command to display help about

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EFIAPI
EblHelpCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINTN   Index;
  CHAR8   *Ptr;
  UINTN   CurrentRow = 0;

  if (Argc == 1) {
    // Print all the commands
    AsciiPrint ("Embedded Boot Loader (EBL) commands (help command for more info):\n");
    CurrentRow++;
    for (Index = 0; Index < mCmdTableNextFreeIndex; Index++) {
      EblSetTextColor (EFI_YELLOW);
      AsciiPrint (" %a", mCmdTable[Index]->Name);
      EblSetTextColor (0);
      AsciiPrint ("%a\n", mCmdTable[Index]->HelpSummary);
      // Handle multi line help summaries
      CurrentRow += CountNewLines (mCmdTable[Index]->HelpSummary);
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
        break;
      }
    }
  } else if (Argv[1] != NULL) {
    // Print specific help
    for (Index = 0, CurrentRow = 0; Index < mCmdTableNextFreeIndex; Index++) {
      if (AsciiStriCmp (Argv[1], mCmdTable[Index]->Name) == 0) {
        Ptr = (mCmdTable[Index]->Help == NULL) ? mCmdTable[Index]->HelpSummary : mCmdTable[Index]->Help;
        AsciiPrint ("%a%a\n", Argv[1], Ptr);
        // Handle multi line help summaries
        CurrentRow += CountNewLines (Ptr);
        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
          break;
        }
      }
    }
  }

  return EFI_SUCCESS;
}
Beispiel #2
0
/**
  Perform a dir on a device. The device must support Simple File System Protocol
  or the FV protocol.

  Argv[0] - "dir"
  Argv[1] - Device Name:path. Path is optional
  Argv[2] - Optional filename to match on. A leading * means match substring
  Argv[3] - Optional FV file type

  dir fs1:\efi      ; perform a dir on fs1: device in the efi directory
  dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but
                      only print out files that contain the string *.efi
  dir fv1:\         ; perform a dir on fv1: device in the efi directory
                    NOTE: fv devices do not contain subdirs
  dir fv1:\ * PEIM  ; will match all files of type PEIM

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EblDirCmd (
    IN UINTN  Argc,
    IN CHAR8  **Argv
)
{
    EFI_STATUS                    Status;
    EFI_OPEN_FILE                 *File;
    EFI_FILE_INFO                 *DirInfo;
    UINTN                         ReadSize;
    UINTN                         CurrentRow;
    CHAR16                        *MatchSubString;
    EFI_STATUS                    GetNextFileStatus;
    UINTN                         Key;
    EFI_FV_FILETYPE               SearchType;
    EFI_FV_FILETYPE               Type;
    EFI_FV_FILE_ATTRIBUTES        Attributes;
    UINTN                         Size;
    EFI_GUID                      NameGuid;
    EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
    UINT32                        AuthenticationStatus;
    VOID                          *Section;
    UINTN                         SectionSize;
    EFI_FV_FILETYPE               Index;
    UINTN                         Length;
    UINTN                         BestMatchCount;
    CHAR16                        UnicodeFileName[MAX_CMD_LINE];
    CHAR8                         *Path;
    CHAR8                         *TypeStr;
    UINTN                         TotalSize;


    if (Argc <= 1) {
        Path = EfiGetCwd ();
        if (Path == NULL) {
            return EFI_SUCCESS;
        }
    } else {
        Path = Argv[1];
    }

    File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
    if (File == NULL) {
        return EFI_SUCCESS;
    }

    if (File->Type == EfiOpenFirmwareVolume) {
        // FV Dir

        SearchType = EFI_FV_FILETYPE_ALL;
        UnicodeFileName[0] = '\0';
        MatchSubString = &UnicodeFileName[0];
        if (Argc > 2) {
            AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);
            if (UnicodeFileName[0] == '*') {
                // Handle *Name substring matching
                MatchSubString = &UnicodeFileName[1];
            }

            // Handle file type matchs
            if (Argc > 3) {
                // match a specific file type, always last argument
                Length = AsciiStrLen (Argv[3]);
                for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) {
                    if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) {
                        // exact match
                        SearchType = Index;
                        break;
                    }

                    if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) {
                        // partial match, so keep looking to make sure there is only one partial match
                        BestMatchCount++;
                        SearchType = Index;
                    }
                }

                if (BestMatchCount > 1) {
                    SearchType = EFI_FV_FILETYPE_ALL;
                }
            }
        }

        TotalSize = 0;
        Fv = File->Fv;
        Key = 0;
        CurrentRow = 0;
        do {
            Type = SearchType;
            GetNextFileStatus = Fv->GetNextFile (
                                    Fv,
                                    &Key,
                                    &Type,
                                    &NameGuid,
                                    &Attributes,
                                    &Size
                                );
            if (!EFI_ERROR (GetNextFileStatus)) {
                TotalSize += Size;
                // Calculate size of entire file
                Section = NULL;
                Size = 0;
                Status = Fv->ReadFile (
                             Fv,
                             &NameGuid,
                             Section,
                             &Size,
                             &Type,
                             &Attributes,
                             &AuthenticationStatus
                         );
                if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {
                    // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid
                    Size = 0;
                }

                TypeStr = (Type <= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) ? gFvFileType[Type] : "UNKNOWN";

                // read the UI seciton to do a name match.
                Section = NULL;
                Status = Fv->ReadSection (
                             Fv,
                             &NameGuid,
                             EFI_SECTION_USER_INTERFACE,
                             0,
                             &Section,
                             &SectionSize,
                             &AuthenticationStatus
                         );
                if (!EFI_ERROR (Status)) {
                    if (StrStr (Section, MatchSubString) != NULL) {
                        AsciiPrint ("%,9d %7a %g %s\n", Size, TypeStr, &NameGuid, Section);
                        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                            break;
                        }
                    }
                    FreePool (Section);
                } else {
                    if (*MatchSubString == '\0') {
                        AsciiPrint ("%,9d %7a %g\n", Size, TypeStr, &NameGuid);
                        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                            break;
                        }
                    }
                }
            }
        } while (!EFI_ERROR (GetNextFileStatus));

        if (SearchType == EFI_FV_FILETYPE_ALL) {
            AsciiPrint ("%,20d bytes in files %,d bytes free\n", TotalSize, File->FvSize - File->FvHeaderSize - TotalSize);
        }


    } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) {
        // Simple File System DIR

        if (File->FsFileInfo ==  NULL) {
            return EFI_SUCCESS;
        }

        if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) {
            return EFI_SUCCESS;
        }

        // Handle *Name substring matching
        MatchSubString = NULL;
        UnicodeFileName[0] = '\0';
        if (Argc > 2) {
            AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);
            if (UnicodeFileName[0] == '*') {
                MatchSubString = &UnicodeFileName[1];
            }
        }

        File->FsFileHandle->SetPosition (File->FsFileHandle, 0);
        for (CurrentRow = 0;;) {
            // First read gets the size
            DirInfo = NULL;
            ReadSize = 0;
            Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);
            if (Status == EFI_BUFFER_TOO_SMALL) {
                // Allocate the buffer for the real read
                DirInfo = AllocatePool (ReadSize);
                if (DirInfo == NULL) {
                    goto Done;
                }

                // Read the data
                Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);
                if ((EFI_ERROR (Status)) || (ReadSize == 0)) {
                    break;
                }
            } else {
                break;
            }

            if (MatchSubString != NULL) {
                if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) {
                    // does not match *name argument, so skip
                    continue;
                }
            } else if (UnicodeFileName[0] != '\0') {
                // is not an exact match for name argument, so skip
                if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) {
                    continue;
                }
            }

            if (DirInfo->Attribute & EFI_FILE_DIRECTORY) {
                AsciiPrint ("         <DIR> %s\n", &DirInfo->FileName[0]);
            } else {
                AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]);
            }

            if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                break;
            }

            FreePool (DirInfo);
        }

Done:
        if (DirInfo != NULL) {
            FreePool (DirInfo);
        }
    }

    EfiClose (File);

    return EFI_SUCCESS;
}
Beispiel #3
0
EFI_STATUS
OutputData (
  IN UINT8  *Address,
  IN UINTN  Length,
  IN UINTN  Width,
  IN UINTN  Offset
  )
{
  UINT8 *EndAddress;
  UINTN Line;
  CHAR8 TextLine[0x11];
  UINTN CurrentRow = 0;
  UINTN Bytes;
  UINTN Spaces   = 0;
  CHAR8 Blanks[80];

  AsciiStrCpyS (Blanks, sizeof Blanks, mBlanks);
  for (EndAddress = Address + Length; Address < EndAddress; Offset += Line) {
    AsciiPrint ("%08x: ", Offset);
    for (Line = 0; (Line < 0x10) && (Address < EndAddress);) {
      Bytes = EndAddress - Address;

      switch (Width) {
        case 4:
          if (Bytes >= 4) {
            AsciiPrint ("%08x ", *((UINT32 *)Address));
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
          } else {
            AsciiPrint ("%08x ", GetBytes(Address, Bytes));
            Address += Bytes;
            Line    += Bytes;
          }
          break;

        case 2:
          if (Bytes >= 2) {
            AsciiPrint ("%04x ", *((UINT16 *)Address));
            TextLine[Line++] = ConvertToTextLine(*Address++);
            TextLine[Line++] = ConvertToTextLine(*Address++);
          } else {
            AsciiPrint ("%04x ", GetBytes(Address, Bytes));
            Address += Bytes;
            Line    += Bytes;
          }
          break;

        case 1:
          AsciiPrint ("%02x ", *((UINT8 *)Address));
          TextLine[Line++] = ConvertToTextLine(*Address++);
          break;

        default:
          AsciiPrint ("Width must be 1, 2, or 4!\n");
          return EFI_INVALID_PARAMETER;
      }
    }

    // Pad spaces
    if (Line < 0x10) {
      switch (Width) {
        case 4:
          Spaces = 9 * ((0x10 - Line)/4);
          break;
        case 2:
          Spaces = 5 * ((0x10 - Line)/2);
          break;
        case 1:
          Spaces = 3 * (0x10 - Line);
          break;
      }

      Blanks[Spaces] = '\0';

      AsciiPrint(Blanks);

      Blanks[Spaces] = ' ';
    }

    TextLine[Line] = 0;
    AsciiPrint ("|%a|\n", TextLine);

    if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
      return EFI_END_OF_FILE;
    }
  }

  if (Length % Width != 0) {
    AsciiPrint ("%08x\n", Offset);
  }

  return EFI_SUCCESS;
}
Beispiel #4
0
/**
  Dump out the EFI memory map

  Argv[0] - "memmap"

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EblMemMapCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS            Status;
  EFI_MEMORY_DESCRIPTOR *MemMap;
  EFI_MEMORY_DESCRIPTOR *OrigMemMap;
  UINTN                 MemMapSize;
  UINTN                 MapKey;
  UINTN                 DescriptorSize;
  UINT32                DescriptorVersion;
  UINT64                PageCount[EfiMaxMemoryType];
  UINTN                 Index;
  UINT64                EntrySize;
  UINTN                 CurrentRow;
  UINT64                TotalMemory;

  ZeroMem (PageCount, sizeof (PageCount));

  AsciiPrint ("EFI Memory Map\n");

  // First call is to figure out how big the buffer needs to be
  MemMapSize = 0;
  MemMap     = NULL;
  Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    // In case the AllocatPool changes the memory map we added in some extra descriptors
    MemMapSize += (DescriptorSize * 0x100);
    OrigMemMap = MemMap = AllocatePool (MemMapSize);
    if (OrigMemMap != NULL) {
      // 2nd time we get the data
      Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);
      if (!EFI_ERROR (Status)) {
        for (Index = 0, CurrentRow = 0; Index < MemMapSize/DescriptorSize; Index++) {
          EntrySize = LShiftU64 (MemMap->NumberOfPages, 12);
          AsciiPrint ("\n%a %016lx - %016lx: # %08lx %016lx", gMemMapType[MemMap->Type % EfiMaxMemoryType], MemMap->PhysicalStart, MemMap->PhysicalStart + EntrySize -1, MemMap->NumberOfPages, MemMap->Attribute);
          if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
            break;
          }

          PageCount[MemMap->Type % EfiMaxMemoryType] += MemMap->NumberOfPages;
          MemMap = NEXT_MEMORY_DESCRIPTOR (MemMap, DescriptorSize);
        }
      }

      for (Index = 0, TotalMemory = 0; Index < EfiMaxMemoryType; Index++) {
        if (PageCount[Index] != 0) {
          AsciiPrint ("\n  %a %,7ld Pages (%,14ld)", gMemMapType[Index], PageCount[Index], LShiftU64 (PageCount[Index], 12));
          if (Index == EfiLoaderCode ||
              Index == EfiLoaderData ||
              Index == EfiBootServicesCode ||
              Index == EfiBootServicesData ||
              Index == EfiRuntimeServicesCode ||
              Index == EfiRuntimeServicesData ||
              Index == EfiConventionalMemory ||
              Index == EfiACPIReclaimMemory ||
              Index == EfiACPIMemoryNVS ||
              Index == EfiPalCode
          ) {
            // Count total memory
            TotalMemory += PageCount[Index];
          }
        }
      }

      AsciiPrint ("\nTotal Memory: %,ld MB (%,ld bytes)\n", RShiftU64 (TotalMemory, 8), LShiftU64 (TotalMemory, 12));

      FreePool (OrigMemMap);

    }
  }

  return EFI_SUCCESS;
}
Beispiel #5
0
/**
  Dump information about devices in the system.

  fv:       PI Firmware Volume
  fs:       EFI Simple File System
  blk:      EFI Block IO
  LoadFile: EFI Load File Protocol (commonly PXE network boot)

  Argv[0] - "device"

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EblDeviceCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINTN         Index;
  UINTN         CurrentRow;
  UINTN         Max;

  CurrentRow = 0;

  // Need to call here to make sure Device Counts are valid
  EblUpdateDeviceLists ();

  // Now we can print out the info...
  Max = EfiGetDeviceCounts (EfiOpenFirmwareVolume);
  if (Max != 0) {
    AsciiPrint ("Firmware Volume Devices:\n");
    for (Index = 0; Index < Max; Index++) {
      EblPrintFvbInfo (EfiDeviceOpenByType (EfiOpenFirmwareVolume, Index));
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
        break;
      }
    }
  }

  Max = EfiGetDeviceCounts (EfiOpenFileSystem);
  if (Max != 0) {
    AsciiPrint ("File System Devices:\n");
    for (Index = 0; Index < Max; Index++) {
      EblPrintFsInfo (EfiDeviceOpenByType (EfiOpenFileSystem, Index));
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
        break;
      }
    }
  }

  Max = EfiGetDeviceCounts (EfiOpenBlockIo);
  if (Max != 0) {
    AsciiPrint ("Block IO Devices:\n");
    for (Index = 0; Index < Max; Index++) {
      EblPrintBlkIoInfo (EfiDeviceOpenByType (EfiOpenBlockIo, Index));
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
        break;
      }
    }
  }

  Max = EfiGetDeviceCounts (EfiOpenLoadFile);
  if (Max != 0) {
    AsciiPrint ("LoadFile Devices: (usually network)\n");
    for (Index = 0; Index < Max; Index++) {
      EblPrintLoadFileInfo (EfiDeviceOpenByType (EfiOpenLoadFile, Index));
      if (EblAnyKeyToContinueQtoQuit (&CurrentRow, TRUE)) {
        break;
      }
    }
  }

  return EFI_SUCCESS;
}