예제 #1
0
/**
  This function is to display the IPv6 address.

  @param[in]  Ip        The pointer to the IPv6 address.

**/
VOID
HttpBootShowIp6Addr (
  IN EFI_IPv6_ADDRESS   *Ip
  )
{
  UINTN                 Index;

  for (Index = 0; Index < 16; Index++) {

    if (Ip->Addr[Index] != 0) {
      AsciiPrint ("%x", Ip->Addr[Index]);
    }
    Index++;
    if (Index > 15) {
      return;
    }
    if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) {
      AsciiPrint ("0");
    }
    AsciiPrint ("%x", Ip->Addr[Index]);
    if (Index < 15) {
      AsciiPrint (":");
    }
  }
}
예제 #2
0
파일: EblCmdMmu.c 프로젝트: B-Rich/edk2
MMU_ENTRY
DumpMmuLevel (
  IN MMU_LEVEL Level,
  IN UINT32* Table,
  IN MMU_ENTRY PreviousEntry
  )
{
  UINT32      Index = 0, Count;
  MMU_ENTRY   LastEntry, Entry;

	ASSERT((Level == Level1) || (Level == Level2));

  if (Level == Level1)    Count = 4096;
  else                    Count = 256;

  // At Level1, we will get into this function because PreviousEntry is not valid
  if (!MmuEntryIsValidAddress((MMU_LEVEL)(Level-1),PreviousEntry.Value)) {
      // Find the first valid address
      for (; (Index < Count) && (!MmuEntryIsValidAddress(Level,Table[Index])); Index++);

      LastEntry = MmuEntryCreate(Level,Table,Index);
      Index++;
  } else {
    LastEntry = PreviousEntry;
  }

  for (; Index < Count; Index++) {
    Entry = MmuEntryCreate(Level,Table,Index);
    if ((Level == Level1) && ((Entry.Value & 0x3) == 1)) {       // We have got a Level2 table redirection
      LastEntry = DumpMmuLevel(Level2,(UINT32*)(Entry.Value & 0xFFFFFC00),LastEntry);
    } else if (!MmuEntryIsValidAddress(Level,Table[Index])) {
      if (MmuEntryIsValidAddress(LastEntry.Level,LastEntry.Value)) {
          AsciiPrint("0x%08X-0x%08X\t%a\n",
              MmuEntryGetAddress(LastEntry),MmuEntryGetAddress(PreviousEntry)+MmuEntryGetSize(PreviousEntry)-1,
              MmuEntryGetAttributesName(LastEntry));
      }
      LastEntry = Entry;
    } else {
      if (MmuEntryGetAttributes(LastEntry) != MmuEntryGetAttributes(Entry)) {
          if (MmuEntryIsValidAddress(Level,LastEntry.Value)) {
            AsciiPrint("0x%08X-0x%08X\t%a\n",
                      MmuEntryGetAddress(LastEntry),MmuEntryGetAddress(PreviousEntry)+MmuEntryGetSize(PreviousEntry)-1,
                      MmuEntryGetAttributesName(LastEntry));
          }
          LastEntry = Entry;
      } else {
        ASSERT(LastEntry.Value != 0);
      }
    }
    PreviousEntry = Entry;
  }

  if ((Level == Level1) && (LastEntry.Index != Index) && MmuEntryIsValidAddress(Level,LastEntry.Value)) {
    AsciiPrint("0x%08X-0x%08X\t%a\n",
                  MmuEntryGetAddress(LastEntry),MmuEntryGetAddress(PreviousEntry)+MmuEntryGetSize(PreviousEntry)-1,
                  MmuEntryGetAttributesName(LastEntry));
  }

  return LastEntry;
}
예제 #3
0
파일: EfiDevice.c 프로젝트: FishYu1222/edk2
/**
  Print information about the File System device.

  @param  File  Open File for the device

**/
VOID
EblPrintFsInfo (
  IN  EFI_OPEN_FILE   *File
  )
{
  CHAR16 *Str;

  if (File == NULL) {
    return;
  }

  AsciiPrint ("  %a: ", File->DeviceName);
  if (File->FsInfo != NULL) {
    for (Str = File->FsInfo->VolumeLabel; *Str != '\0'; Str++) {
      if (*Str == ' ') {
        // UI makes you enter _ for space, so make the printout match that
        *Str = '_';
      }
      AsciiPrint ("%c", *Str);
    }
    AsciiPrint (":");
    if (File->FsInfo->ReadOnly) {
      AsciiPrint ("ReadOnly");
    }
  }

  AsciiPrint ("\n");
  EfiClose (File);
}
예제 #4
0
파일: Main.c 프로젝트: EvanLloyd/tianocore
/**
  This routine is used prevent command output data from scrolling off the end
  of the screen. The global gPageBreak is used to turn on or off this feature.
  If the CurrentRow is near the end of the screen pause and print out a prompt
  If the use hits Q to quit return TRUE else for any other key return FALSE.
  PrefixNewline is used to figure out if a newline is needed before the prompt
  string. This depends on the last print done before calling this function.
  CurrentRow is updated by one on a call or set back to zero if a prompt is
  needed.

  @param  CurrentRow  Used to figure out if its the end of the page and updated
  @param  PrefixNewline  Did previous print issue a newline

  @return TRUE if Q was hit to quit, FALSE in all other cases.

**/
BOOLEAN
EFIAPI
EblAnyKeyToContinueQtoQuit (
  IN  UINTN   *CurrentRow,
  IN  BOOLEAN PrefixNewline
  )
{
  EFI_INPUT_KEY     InputKey;

  if (!gPageBreak) {
    // global disable for this feature
    return FALSE;
  }

  if (*CurrentRow >= (gScreenRows - 2)) {
    if (PrefixNewline) {
      AsciiPrint ("\n");
    }
    AsciiPrint ("Any key to continue (Q to quit): ");
    EblGetCharKey (&InputKey, 0, NULL);
    AsciiPrint ("\n");

    // Time to promt to stop the screen. We have to leave space for the prompt string
    *CurrentRow = 0;
    if (InputKey.UnicodeChar == 'Q' || InputKey.UnicodeChar == 'q') {
      return TRUE;
    }
  } else {
    *CurrentRow += 1;
  }

  return FALSE;
}
예제 #5
0
파일: EblCmdLib.c 프로젝트: Cutty/edk2
/**
  Simple arm disassembler via a library

  Argv[0] - symboltable
  Argv[1] - Optional qoted format string 
  Argv[2] - Optional flag

  @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
EblSymbolTable (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                        Status;
  EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugImageTableHeader = NULL;
  EFI_DEBUG_IMAGE_INFO              *DebugTable;
  UINTN                             Entry;
  CHAR8                             *Format;
  CHAR8                             *Pdb;
  UINT32                            PeCoffSizeOfHeaders;
  UINT32                            ImageBase;
  BOOLEAN                           Elf;
  
  // Need to add lots of error checking on the passed in string
  // Default string is for RealView debugger
#if (__ARMCC_VERSION < 500000)
  Format = (Argc > 1) ? Argv[1] : "load /a /ni /np %a &0x%x";
#else
  Format = (Argc > 1) ? Argv[1] : "add-symbol-file %a 0x%x";
#endif
  Elf = (Argc > 2) ? FALSE : TRUE;
  
  Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&DebugImageTableHeader);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  DebugTable = DebugImageTableHeader->EfiDebugImageInfoTable;
  if (DebugTable == NULL) {
    return EFI_SUCCESS;
  }

  for (Entry = 0; Entry < DebugImageTableHeader->TableSize; Entry++, DebugTable++) {
    if (DebugTable->NormalImage != NULL) {
      if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
        ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
        PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)ImageBase);
        Pdb = PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
        if (Pdb != NULL) {
          if (Elf) {
            // ELF and Mach-O images don't include the header so the linked address does not include header
            ImageBase += PeCoffSizeOfHeaders;
          } 
          AsciiPrint (Format, Pdb, ImageBase);
          AsciiPrint ("\n");
        } else {
        }
      }
    }  
  }

  return EFI_SUCCESS;
}
예제 #6
0
파일: Main.c 프로젝트: EvanLloyd/tianocore
/**
  Print the prompt for the EBL.
**/
VOID
EblPrompt (
  VOID
  )
{
  EblSetTextColor (EFI_YELLOW);
  AsciiPrint ("%a %a",(CHAR8 *)PcdGetPtr (PcdEmbeddedPrompt), EfiGetCwd ());
  EblSetTextColor (0);
  AsciiPrint ("%a", ">");
}
예제 #7
0
파일: Main.c 프로젝트: EvanLloyd/tianocore
/**
  Print the boot up banner for the EBL.
**/
VOID
EblPrintStartupBanner (
  VOID
  )
{
  AsciiPrint ("Embedded Boot Loader (");
  EblSetTextColor (EFI_YELLOW);
  AsciiPrint ("EBL");
  EblSetTextColor (0);
  AsciiPrint (") prototype. Built at %a on %a\n",__TIME__, __DATE__);
  AsciiPrint ("THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN 'AS IS' BASIS,\nWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\n");
  AsciiPrint ("Please send feedback to [email protected]\n");
}
예제 #8
0
/**
  This function is to display the IPv4 address.

  @param[in]  Ip        The pointer to the IPv4 address.

**/
VOID
HttpBootShowIp4Addr (
  IN EFI_IPv4_ADDRESS   *Ip
  )
{
  UINTN                 Index;

  for (Index = 0; Index < 4; Index++) {
    AsciiPrint ("%d", Ip->Addr[Index]);
    if (Index < 3) {
      AsciiPrint (".");
    }
  }
}
예제 #9
0
파일: Main.c 프로젝트: FishYu1222/edk2
/**
  Entry point with Argc, Argv. Put your code here.

  @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
EblMain (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINTN   Index;

  AsciiPrint ("Hello World\n");
  for (Index = 0; Index < Argc; Index++) {
    AsciiPrint ("Argv[%d] = %a\n", Index, Argv[Index]);
  }

  return EFI_SUCCESS;
}
예제 #10
0
/**
  Simple arm disassembler via a library

  Argv[0] - disasm
  Argv[1] - Address to start disassembling from
  ARgv[2] - Number of instructions to disassembly (optional)

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

  @return EFI_SUCCESS

**/
EFI_STATUS
EblDisassembler (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINT8   *Ptr, *CurrentAddress;
  UINT32  Address;
  UINT32  Count;
  CHAR8   Buffer[80];
  UINT32  ItBlock;
  
  if (Argc < 2) {
    return EFI_INVALID_PARAMETER;
  }
  
  Address = AsciiStrHexToUintn (Argv[1]);
  Count   = (Argc > 2) ? (UINT32)AsciiStrHexToUintn (Argv[2]) : 20;

  Ptr = (UINT8 *)(UINTN)Address;  
  ItBlock = 0;
  do {
    CurrentAddress = Ptr;
    DisassembleInstruction (&Ptr, TRUE, TRUE, &ItBlock, Buffer, sizeof (Buffer));
    AsciiPrint ("0x%08x: %a\n", CurrentAddress, Buffer);
  } while (Count-- > 0);
 

  return EFI_SUCCESS;
}
예제 #11
0
파일: HwIoDebug.c 프로젝트: FishYu1222/edk2
/**
  Read from IO space

  Argv[0] - "ioread"[.#] # is optional width 1, 2, or 4. Default 1
  Argv[1] - Hex IO address

  ior.4 0x3f8  ;Do a 32-bit IO Read from 0x3f8
  ior   0x3f8  ;Do a  8-bit IO Read from 0x3f8

  @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
EblIoReadCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINTN   Width;
  UINTN   Port;
  UINTN   Data;

  if (Argc < 2) {
    return EFI_INVALID_PARAMETER;
  }

  Port = AsciiStrHexToUintn (Argv[1]);
  Width = WidthFromCommandName (Argv[0], 1);

  if (Width == 1) {
    Data = IoRead8 (Port);
  } else if (Width == 2) {
    Data = IoRead16 (Port);
  } else if (Width == 4) {
    Data = IoRead32 (Port);
  } else {
    return EFI_INVALID_PARAMETER;
  }

  AsciiPrint ("0x%04x = 0x%x", Port, Data);

  return EFI_SUCCESS;
}
예제 #12
0
/**
  Update the screen by decrementing the timeout value.
  This AsciiPrint has to match the AsciiPrint in
  EblPauseCmd.

  @param  ElaspedTime   Current timeout value remaining

**/
VOID
EFIAPI
EblPauseCallback (
  IN  UINTN   ElapsedTime
  )
{
  AsciiPrint ("\b\b\b\b\b\b\b\b\b\b\b\b   \b\b%3d seconds", ElapsedTime);
}
예제 #13
0
파일: Script.c 프로젝트: hsienchieh/uefilab
/**
  Execute the passed in file like a series of commands. The ; can be used on
  a single line to indicate multiple commands per line. The Ascii text file 
  can contain any number of lines. The following line termination forms are 
  supported:
    LF   : Unix, Mac OS X*, BeOS
    CR+LF: MS-DOS*, Microsoft Windows*
    CR   : Commodore, Apple II, and really Mac OS
    LF+CR: for simplicity and completeness 

  Argv[0] - "script"
  Argv[1] - Device Name:path for the file to load

  script fv1:\script.txt

  @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
EblScriptCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                    Status;
  EFI_OPEN_FILE                 *File;
  VOID                          *Address;
  UINTN                         Size;
  CHAR8                         *Ptr;
  CHAR8                         *ScanPtr;
  UINTN                         CmdLineSize;
  
  

  if (Argc < 2) {
    // file name required
    return EFI_SUCCESS;
  }

  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    AsciiPrint ("  %a is not a valid path\n", Argv[1]);
    return EFI_SUCCESS;
  }

  Status = EfiReadAllocatePool (File, &Address, &Size);
  if (!EFI_ERROR (Status)) {
    // Loop through each line in the text file
    for (Ptr = (CHAR8 *)Address; (Ptr < (((CHAR8 *)Address) + Size)) && !EFI_ERROR (Status); Ptr += CmdLineSize) {
      for (CmdLineSize = 0, ScanPtr = Ptr; ; CmdLineSize++, ScanPtr++) {
        // look for the end of the line
        if ((*ScanPtr == EBL_CR) || (*ScanPtr == EBL_LF)) {
          // convert to NULL as this is what input routine would do
          *ScanPtr = 0;
          if ((*(ScanPtr + 1) == EBL_CR) || (*(ScanPtr + 1) == EBL_LF)) {
            // if its a set get the 2nd EOL char
            CmdLineSize++;
            *(ScanPtr + 1) = 0;
          }
          CmdLineSize++;
          break;
        }
        
      }

      Status = ProcessCmdLine (Ptr, CmdLineSize);
    }
  
    FreePool (Address);
  }
 
  EfiClose (File);
  return Status;
}
예제 #14
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;
}
예제 #15
0
파일: EfiDevice.c 프로젝트: FishYu1222/edk2
 /**
  Print information about the Load File devices.
  If the device supports PXE dump out extra information

  @param  File  Open File for the device

**/
VOID
EblPrintLoadFileInfo (
  IN  EFI_OPEN_FILE   *File
  )
{
  EFI_DEVICE_PATH_PROTOCOL    *DevicePathNode;
  MAC_ADDR_DEVICE_PATH        *MacAddr;
  UINTN                       HwAddressSize;
  UINTN                       Index;

  if (File == NULL) {
    return;
  }

  AsciiPrint ("  %a: %a ", File->DeviceName, EblLoadFileBootTypeString (File->EfiHandle));

  if (File->DevicePath != NULL) {
    // Try to print out the MAC address
    for (DevicePathNode = File->DevicePath;
        !IsDevicePathEnd (DevicePathNode);
        DevicePathNode = NextDevicePathNode (DevicePathNode)) {

      if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePathNode) == MSG_MAC_ADDR_DP)) {
        MacAddr = (MAC_ADDR_DEVICE_PATH *)DevicePathNode;

        HwAddressSize = sizeof (EFI_MAC_ADDRESS);
        if (MacAddr->IfType == 0x01 || MacAddr->IfType == 0x00) {
          HwAddressSize = 6;
        }

        AsciiPrint ("MAC ");
        for (Index = 0; Index < HwAddressSize; Index++) {
          AsciiPrint ("%02x", MacAddr->MacAddress.Addr[Index] & 0xff);
        }
      }
    }
  }

  AsciiPrint ("\n");
  EfiClose (File);
  return;
}
예제 #16
0
파일: EblCmdMmu.c 프로젝트: B-Rich/edk2
EFI_STATUS
EblDumpMmu (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  UINT32  *TTEntry;
  MMU_ENTRY NoEntry;

  TTEntry = ArmGetTTBR0BaseAddress();

  AsciiPrint ("\nTranslation Table:0x%X\n",TTEntry);
  AsciiPrint ("Address Range\t\tAttributes\n");
  AsciiPrint ("____________________________________________________\n");

  NoEntry.Level = (MMU_LEVEL)200;
  DumpMmuLevel(Level1,TTEntry,NoEntry);

  return EFI_SUCCESS;
}
예제 #17
0
파일: EfiDevice.c 프로젝트: FishYu1222/edk2
/**
  Print information about the FV devices.

  @param  File  Open File for the device

**/
VOID
EblPrintFvbInfo (
  IN  EFI_OPEN_FILE   *File
  )
{
  if (File == NULL) {
    return;
  }

  AsciiPrint ("  %a: 0x%08lx - 0x%08lx : 0x%08x\n", File->DeviceName, File->FvStart, File->FvStart + File->FvSize - 1, File->FvSize);
  EfiClose (File);
}
예제 #18
0
/**
  Pause until a key is pressed and abort the remaining commands on the command
  line. If no key is pressed continue processing the command line. This command
  allows the user to stop an operation from happening and return control to the
  command prompt.

  Argv[0] - "pause"
  Argv[1] - timeout value is decimal seconds

  @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  Timeout expired with no input
  @return EFI_TIMEOUT  Stop processing other commands on the same command line

**/
EFI_STATUS
EFIAPI
EblPauseCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS      Status;
  UINTN           Delay;
  EFI_INPUT_KEY   Key;

  Delay = (Argc == 1)? 10 : AsciiStrDecimalToUintn (Argv[1]);

  AsciiPrint ("Hit any key to break. You have %3d seconds", Delay);
  Status = EblGetCharKey (&Key, Delay, EblPauseCallback);
  AsciiPrint ("\n");

  // If we timeout then the pause succeeded thus return success
  // If we get a key return timeout to stop other command on this cmd line
  return (Status == EFI_SUCCESS) ? EFI_TIMEOUT : EFI_SUCCESS;;
}
예제 #19
0
파일: EfiFileLib.c 프로젝트: M1cha/edk2
/**
Close a file handle opened by EfiOpen() and free all resources allocated by
EfiOpen().

@param  Stream    Open File Handle

@return EFI_INVALID_PARAMETER  Stream is not an Open File
@return EFI_SUCCESS            Steam closed

**/
EFI_STATUS
EfiClose (
  IN  EFI_OPEN_FILE     *File
  )
{
  EFI_STATUS          Status;
  UINT64              TftpBufferSize;

  if (!FileHandleValid (File)) {
    return EFI_INVALID_PARAMETER;
  }

  //Write the buffer contents to TFTP file.
  if ((File->Type == EfiOpenTftp) && (File->IsDirty)) {

    TftpBufferSize = File->Size;
    Status = EblMtftp (
      EFI_PXE_BASE_CODE_TFTP_WRITE_FILE,
      File->Buffer,
      TRUE,
      &TftpBufferSize,
      NULL,
      &File->ServerIp,
      (UINT8 *)File->FileName,
      NULL,
      FALSE
      );
    if (EFI_ERROR(Status)) {
      AsciiPrint("TFTP error during APPLE_NSP_TFTP_WRITE_FILE: %r\n", Status);
      return Status;
    }
  }

  if ((File->Type == EfiOpenLoadFile) ||
    ((File->Type == EfiOpenTftp) && (File->IsBufferValid == TRUE)) ||
    ((File->Type == EfiOpenFirmwareVolume) && (File->IsBufferValid == TRUE))) {
    EblFreePool(File->Buffer);
  }

  EblFreePool (File->DevicePath);
  EblFreePool (File->DeviceName);
  EblFreePool (File->FsFileInfo);
  EblFreePool (File->FsInfo);

  if (File->FsFileHandle != NULL) {
    File->FsFileHandle->Close (File->FsFileHandle);
  }

  // Need to free File and it's Guard structures
  EblFreePool (BASE_CR (File, EFI_OPEN_FILE_GUARD, File));
  return EFI_SUCCESS;
}
예제 #20
0
파일: Main.c 프로젝트: EvanLloyd/tianocore
/**
  Parse a command line and execute the commands. The ; separator allows
  multiple commands for each command line. Stop processing if one of the
  commands returns an error.

  @param  CmdLine          Command Line to process.
  @param  MaxCmdLineSize   MaxSize of the Command line

  @return EFI status of the Command

**/
EFI_STATUS
ProcessCmdLine (
  IN CHAR8      *CmdLine,
  IN UINTN      MaxCmdLineSize
  )
{
  EFI_STATUS          Status;
  EBL_COMMAND_TABLE   *Cmd;
  CHAR8               *Ptr;
  UINTN               Argc;
  CHAR8               *Argv[MAX_ARGS];

  // Parse the command line. The loop processes commands separated by ;
  for (Ptr = CmdLine, Status = EFI_SUCCESS; Ptr != NULL;) {
    Ptr = ParseArguments (Ptr, &Argc, Argv);
    if (Argc != 0) {
      Cmd = EblGetCommand (Argv[0]);
      if (Cmd != NULL) {
        // Execute the Command!
        Status = Cmd->Command (Argc, Argv);
        if (Status == EFI_ABORTED) {
          // exit command so lets exit
          break;
        } else if (Status == EFI_TIMEOUT) {
          // pause command got input so don't process any more cmd on this cmd line
          break;
        } else if (EFI_ERROR (Status)) {
          AsciiPrint ("%a returned %r error\n", Cmd->Name, Status);
          // if any command fails stop processing CmdLine
          break;
        }
      } else {
        AsciiPrint ("The command '%a' is not supported.\n", Argv[0]);
      }
    }
  }

  return Status;
}
예제 #21
0
파일: Main.c 프로젝트: EvanLloyd/tianocore
/**
  Collect the keyboard input for a cmd line. Carriage Return, New Line, or ESC
  terminates the command line. You can edit the command line via left arrow,
  delete and backspace and they all back up and erase the command line.
  No edit of command line is possible without deletion at this time!
  The up arrow and down arrow fill Cmd with information from the history
  buffer.

  @param  Cmd         Command line to return
  @param  CmdMaxSize  Maximum size of Cmd

  @return The Status of EblGetCharKey()

**/
EFI_STATUS
GetCmd (
  IN OUT  CHAR8   *Cmd,
  IN      UINTN   CmdMaxSize
  )
{
  EFI_STATUS    Status;
  UINTN         Index;
  UINTN         Index2;
  CHAR8         Char;
  CHAR8         *History;
  EFI_INPUT_KEY Key;

  for (Index = 0; Index < CmdMaxSize - 1;) {
    Status = EblGetCharKey (&Key, 0, NULL);
    if (EFI_ERROR (Status)) {
      Cmd[Index] = '\0';
      AsciiPrint ("\n");
      return Status;
    }

    Char = (CHAR8)Key.UnicodeChar;
    if ((Char == '\n') || (Char == '\r') || (Char == 0x7f)) {
      Cmd[Index] = '\0';
      if (FixedPcdGetBool(PcdEmbeddedShellCharacterEcho) == TRUE) {
        AsciiPrint ("\n\r");
      }
      return EFI_SUCCESS;
    } else if ((Char == '\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){
      if (Index != 0) {
        Index--;
        //
        // Update the display
        //
        AsciiPrint ("\b \b");
      }
    } else if ((Key.ScanCode == SCAN_UP) || Key.ScanCode == SCAN_DOWN) {
      History = GetCmdHistory (Key.ScanCode);
      //
      // Clear display line
      //
      for (Index2 = 0; Index2 < Index; Index2++) {
        AsciiPrint ("\b \b");
      }
      AsciiPrint (History);
      Index = AsciiStrLen (History);
      AsciiStrnCpyS (Cmd, CmdMaxSize, History, CmdMaxSize);
    } else {
      Cmd[Index++] = Char;
      if (FixedPcdGetBool(PcdEmbeddedShellCharacterEcho) == TRUE) {
        AsciiPrint ("%c", Char);
      }
    }
  }

  return EFI_SUCCESS;
}
예제 #22
0
파일: EblCmdLib.c 프로젝트: Cutty/edk2
EFI_STATUS
EblDevicePaths (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS Status;
  UINTN                              HandleCount;
  EFI_HANDLE                         *HandleBuffer;
  UINTN                              Index;
  CHAR16*                            String;
  EFI_DEVICE_PATH_PROTOCOL*          DevicePathProtocol;
  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL*  DevicePathToTextProtocol;

  BdsConnectAllDrivers();

  Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
  if (EFI_ERROR (Status)) {
    AsciiPrint ("Did not find the DevicePathToTextProtocol.\n");
    return EFI_SUCCESS;
  }

  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &HandleCount, &HandleBuffer);
  if (EFI_ERROR (Status)) {
    AsciiPrint ("No device path found\n");
    return EFI_SUCCESS;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
    String = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathProtocol,TRUE,TRUE);
    Print (L"[0x%X] %s\n",(UINTN)HandleBuffer[Index], String);
  }

  return EFI_SUCCESS;
}
예제 #23
0
/**
  Display the string of the boot item.

  If the length of the boot item string beyond 70 Char, just display 70 Char.

  @param[in]  Str           The pointer to the string.
  @param[in]  Len           The length of the string.

**/
VOID
PxeBcDisplayBootItem (
  IN UINT8                 *Str,
  IN UINT8                 Len
  )
{
  UINT8                    Tmp;

  //
  // Cut off the chars behind 70th.
  //
  Len       = (UINT8) MIN (PXEBC_DISPLAY_MAX_LINE, Len);
  Tmp       = Str[Len];
  Str[Len]  = 0;
  AsciiPrint ("%a \n", Str);

  //
  // Restore the original 70th char.
  //
  Str[Len]  = Tmp;
}
예제 #24
0
파일: EfiDevice.c 프로젝트: FishYu1222/edk2
/**
  Print information about the Blk IO devices.
  If the device supports PXE dump out extra information

  @param  File  Open File for the device

**/
VOID
EblPrintBlkIoInfo (
  IN  EFI_OPEN_FILE   *File
  )
{
  UINT64                    DeviceSize;
  UINTN                     Index;
  UINTN                     Max;
  EFI_OPEN_FILE             *FsFile;

  if (File == NULL) {
    return;
  }

  AsciiPrint ("  %a: ", File->DeviceName);

  // print out name of file system, if any, on this block device
  Max = EfiGetDeviceCounts (EfiOpenFileSystem);
  if (Max != 0) {
    for (Index = 0; Index < Max; Index++) {
      FsFile = EfiDeviceOpenByType (EfiOpenFileSystem, Index);
      if (FsFile != NULL) {
        if (FsFile->EfiHandle == File->EfiHandle) {
          AsciiPrint ("fs%d: ", Index);
          EfiClose (FsFile);
          break;
        }
        EfiClose (FsFile);
      }
    }
  }

  // Print out useful Block IO media properties
  if (File->FsBlockIoMedia->RemovableMedia) {
    AsciiPrint ("Removable ");
  }
  if (!File->FsBlockIoMedia->MediaPresent) {
    AsciiPrint ("No Media\n");
  } else {
    if (File->FsBlockIoMedia->LogicalPartition) {
      AsciiPrint ("Partition ");
    }
    DeviceSize = MultU64x32 (File->FsBlockIoMedia->LastBlock + 1, File->FsBlockIoMedia->BlockSize);
    AsciiPrint ("Size = 0x%lX\n", DeviceSize);
  }
  EfiClose (File);
}
예제 #25
0
파일: Variable.c 프로젝트: Gshoe2006/edk2
EFI_STATUS
EFIAPI
EblSetCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS    Status = EFI_INVALID_PARAMETER;
  CHAR8*        AsciiVariableSetting = NULL;
  CHAR8*        AsciiVariableName;
  CHAR8*        AsciiValue;
  UINT32        AsciiValueLength;
  CHAR16*       VariableName;
  UINT32        Index;
  UINT32        EscapedQuotes = 0;
  BOOLEAN       Volatile = FALSE;

  if (Argc == 1) {
    AsciiPrint("Variable name is missing.\n");
    return Status;
  }

  for (Index = 1; Index < Argc; Index++) {
    if (AsciiStrCmp(Argv[Index],"-v") == 0) {
      Volatile = 0;
    } else if (Argv[Index][0] == '-') {
      AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);
    } else {
      AsciiVariableSetting = Argv[Index];
    }
  }

  if (AsciiVariableSetting == NULL) {
    AsciiPrint("Variable name is missing.\n");
    return Status;
  }

  // Check if it is a valid variable setting
  AsciiValue = AsciiStrStr (AsciiVariableSetting,"=");
  if (AsciiValue == NULL) {
    //
    // There is no value. It means this variable will be deleted
    //

    // Convert VariableName into Unicode
    VariableName = AllocatePool((AsciiStrLen (AsciiVariableSetting) + 1) * sizeof (CHAR16));
    AsciiStrToUnicodeStr (AsciiVariableSetting,VariableName);

    Status = gRT->SetVariable (
                          VariableName,
                          &gEfiGlobalVariableGuid,
                          ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |
                          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                          0,
                          NULL
                          );
    if (!EFI_ERROR(Status)) {
      AsciiPrint("Variable '%s' deleted\n",VariableName);
    } else {
      AsciiPrint("Variable setting is incorrect. It should be VariableName=Value\n");
    }
    return Status;
  }

  AsciiValue[0] = '\0';
  AsciiVariableName = AsciiVariableSetting;
  AsciiValue++;

  // Clean AsciiValue from quote
  if (AsciiValue[0] == '"') {
    AsciiValue++;
  }
  AsciiValueLength = AsciiStrLen (AsciiValue);
  if ((AsciiValue[AsciiValueLength-2] != '\\') && (AsciiValue[AsciiValueLength-1] == '"')) {
    AsciiValue[AsciiValueLength-1] = '\0';
  }

  // Clean AsciiValue from escaped quotes
  for (Index = 0; Index < AsciiValueLength; Index++) {
    if ((Index > 0) && (AsciiValue[Index-1] == '\\') && (AsciiValue[Index] == '"')) {
      EscapedQuotes++;
    }
    AsciiValue[Index-EscapedQuotes] = AsciiValue[Index];
  }
  // Fill the end of the value with '\0'
  for (Index = 0; Index < EscapedQuotes; Index++) {
    AsciiValue[AsciiValueLength-1-Index] = '\0';
  }

  // Convert VariableName into Unicode
  VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16));
  AsciiStrToUnicodeStr (AsciiVariableName,VariableName);

  Status = gRT->SetVariable (
                      VariableName,
                      &gEfiGlobalVariableGuid,
                      ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |
                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                      AsciiStrLen (AsciiValue)+1,
                      AsciiValue
                      );
  if (!EFI_ERROR(Status)) {
    AsciiPrint("'%a'='%a'\n",AsciiVariableName,AsciiValue);
  }

  return Status;
}
예제 #26
0
파일: Variable.c 프로젝트: Gshoe2006/edk2
EFI_STATUS
EFIAPI
EblGetCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS        Status = EFI_INVALID_PARAMETER;
  UINTN       Size;
  VOID*       Value;
  CHAR8*      AsciiVariableName = NULL;
  CHAR16*     VariableName;
  UINT32      Index;

  if (Argc == 1) {
    AsciiPrint("Variable name is missing.\n");
    return Status;
  }

  for (Index = 1; Index < Argc; Index++) {
    if (Argv[Index][0] == '-') {
      AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);
    } else {
      AsciiVariableName = Argv[Index];
    }
  }

  if (AsciiVariableName == NULL) {
    AsciiPrint("Variable name is missing.\n");
    return Status;
  } else {
    VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16));
    AsciiStrToUnicodeStr (AsciiVariableName,VariableName);
  }

  // Try to get the variable size.
  Value = NULL;
  Size = 0;
  Status = gRT->GetVariable (VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);
  if (Status == EFI_NOT_FOUND) {
    AsciiPrint("Variable name '%s' not found.\n",VariableName);
  } else if (Status == EFI_BUFFER_TOO_SMALL) {
    // Get the environment variable value
    Value = AllocatePool (Size);
    if (Value == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);
    if (EFI_ERROR (Status)) {
      AsciiPrint("Error: '%r'\n",Status);
    } else {
      AsciiPrint("%a=%a\n",AsciiVariableName,Value);
    }
    FreePool(Value);
  } else {
    AsciiPrint("Error: '%r'\n",Status);
  }

  FreePool(VariableName);
  return Status;
}
예제 #27
0
/**
  Attempt to download the boot file through HTTP message exchange.

  @param[in]          Private         The pointer to the driver's private data.
  @param[in, out]     BufferSize      On input the size of Buffer in bytes. On output with a return
                                      code of EFI_SUCCESS, the amount of data transferred to
                                      Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
                                      the size of Buffer required to retrieve the requested file.
  @param[in]          Buffer          The memory buffer to transfer the file to. If Buffer is NULL,
                                      then the size of the requested file is returned in
                                      BufferSize.
  @param[out]         ImageType       The image type of the downloaded file.

  @retval EFI_SUCCESS                 Boot file was loaded successfully.
  @retval EFI_INVALID_PARAMETER       Private is NULL, or ImageType is NULL, or BufferSize is NULL.
  @retval EFI_INVALID_PARAMETER       *BufferSize is not zero, and Buffer is NULL.
  @retval EFI_NOT_STARTED             The driver is in stopped state.
  @retval EFI_BUFFER_TOO_SMALL        The BufferSize is too small to read the boot file. BufferSize has
                                      been updated with the size needed to complete the request.
  @retval EFI_DEVICE_ERROR            An unexpected network error occurred.
  @retval Others                      Other errors as indicated.

**/
EFI_STATUS
HttpBootLoadFile (
  IN     HTTP_BOOT_PRIVATE_DATA       *Private,
  IN OUT UINTN                        *BufferSize,
  IN     VOID                         *Buffer,       OPTIONAL
     OUT HTTP_BOOT_IMAGE_TYPE         *ImageType
  )
{
  EFI_STATUS             Status;

  if (Private == NULL || ImageType == NULL || BufferSize == NULL ) {
    return EFI_INVALID_PARAMETER;
  }

  if (*BufferSize != 0 && Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!Private->Started) {
    return EFI_NOT_STARTED;
  }

  Status = HttpBootInstallCallback (Private);
  if (EFI_ERROR(Status)) {
    goto ON_EXIT;
  }

  if (Private->BootFileUri == NULL) {
    //
    // Parse the cached offer to get the boot file URL first.
    //
    Status = HttpBootDiscoverBootInfo (Private);
    if (EFI_ERROR (Status)) {
      AsciiPrint ("\n  Error: Could not retrieve NBP file size from HTTP server.\n");
      goto ON_EXIT;
    }
  }

  if (!Private->HttpCreated) {
    //
    // Create HTTP child.
    //
    Status = HttpBootCreateHttpIo (Private);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  if (Private->BootFileSize == 0) {
    //
    // Discover the information about the bootfile if we haven't.
    //

    //
    // Try to use HTTP HEAD method.
    //
    Status = HttpBootGetBootFile (
               Private,
               TRUE,
               &Private->BootFileSize,
               NULL,
               &Private->ImageType
               );
    if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
      //
      // Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.
      //
      ASSERT (Private->BootFileSize == 0);
      Status = HttpBootGetBootFile (
                 Private,
                 FALSE,
                 &Private->BootFileSize,
                 NULL,
                 &Private->ImageType
                 );
      if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
        AsciiPrint ("\n  Error: Could not retrieve NBP file size from HTTP server.\n");
        goto ON_EXIT;
      }
    }
  }

  if (*BufferSize < Private->BootFileSize) {
    *BufferSize = Private->BootFileSize;
    *ImageType = Private->ImageType;
    Status = EFI_BUFFER_TOO_SMALL;
    goto ON_EXIT;
  }

  //
  // Load the boot file into Buffer
  //
  Status = HttpBootGetBootFile (
             Private,
             FALSE,
             BufferSize,
             Buffer,
             ImageType
             );

ON_EXIT:
  HttpBootUninstallCallback (Private);

  if (EFI_ERROR (Status)) {
    if (Status == EFI_ACCESS_DENIED) {
      AsciiPrint ("\n  Error: Could not establish connection with HTTP server.\n");
    } else if (Status == EFI_BUFFER_TOO_SMALL && Buffer != NULL) {
      AsciiPrint ("\n  Error: Buffer size is smaller than the requested file.\n");
    } else if (Status == EFI_OUT_OF_RESOURCES) {
      AsciiPrint ("\n  Error: Could not allocate I/O buffers.\n");
    } else if (Status == EFI_DEVICE_ERROR) {
      AsciiPrint ("\n  Error: Network device error.\n");
    } else if (Status == EFI_TIMEOUT) {
      AsciiPrint ("\n  Error: Server response timeout.\n");
    } else if (Status == EFI_ABORTED) {
      AsciiPrint ("\n  Error: Remote boot cancelled.\n");
    } else if (Status != EFI_BUFFER_TOO_SMALL) {
      AsciiPrint ("\n  Error: Unexpected network error.\n");
    }
  }

  return Status;
}
예제 #28
0
파일: BootMenu.c 프로젝트: FishYu1222/edk2
EFI_STATUS
BootMenuMain (
  VOID
  )
{
  LIST_ENTRY                    BootOptionsList;
  UINTN                         OptionCount;
  UINTN                         BootOptionCount;
  EFI_STATUS                    Status;
  LIST_ENTRY*                   Entry;
  BDS_LOAD_OPTION*              BootOption;
  UINTN                         BootOptionSelected;
  UINTN                         Index;
  UINTN                         BootMainEntryCount;
  BOOLEAN                       IsUnicode;

  BootOption         = NULL;
  BootMainEntryCount = sizeof(BootMainEntries) / sizeof(struct BOOT_MAIN_ENTRY);

  while (TRUE) {
    // Get Boot#### list
    BootOptionList (&BootOptionsList);

    OptionCount = 1;

    // Display the Boot options
    for (Entry = GetFirstNode (&BootOptionsList);
         !IsNull (&BootOptionsList,Entry);
         Entry = GetNextNode (&BootOptionsList,Entry)
         )
    {
      BootOption = LOAD_OPTION_FROM_LINK(Entry);

      Print(L"[%d] %s\n", OptionCount, BootOption->Description);

      DEBUG_CODE_BEGIN();
        CHAR16*                           DevicePathTxt;
        EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
        ARM_BDS_LOADER_OPTIONAL_DATA*     OptionalData;
        UINTN                             CmdLineSize;
        ARM_BDS_LOADER_TYPE               LoaderType;

        Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
        if (EFI_ERROR(Status)) {
          // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe)
          DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n"));
          return Status;
        }
        DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE);

        Print(L"\t- %s\n",DevicePathTxt);

        // If it is a supported BootEntry then print its details
        if (IS_ARM_BDS_BOOTENTRY (BootOption)) {
          OptionalData = BootOption->OptionalData;
          LoaderType = (ARM_BDS_LOADER_TYPE)ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);
          if ((LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) || (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT)) {
            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.InitrdSize) > 0) {
              CmdLineSize = ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize);
              DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (
                  GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(&OptionalData->Arguments.LinuxArguments + 1) + CmdLineSize)), TRUE, TRUE);
              Print(L"\t- Initrd: %s\n", DevicePathTxt);
            }
            if (ReadUnaligned16 (&OptionalData->Arguments.LinuxArguments.CmdLineSize) > 0) {
              Print(L"\t- Arguments: %a\n", (&OptionalData->Arguments.LinuxArguments + 1));
            }
          }

          switch (LoaderType) {
            case BDS_LOADER_EFI_APPLICATION:
              Print(L"\t- LoaderType: EFI Application\n");
              break;

            case BDS_LOADER_KERNEL_LINUX_ATAG:
              Print(L"\t- LoaderType: Linux kernel with ATAG support\n");
              break;

            case BDS_LOADER_KERNEL_LINUX_FDT:
              Print(L"\t- LoaderType: Linux kernel with FDT support\n");
              break;

            default:
              Print(L"\t- LoaderType: Not recognized (%d)\n", LoaderType);
          }
        } else if (BootOption->OptionalData != NULL) {
          if (IsPrintableString (BootOption->OptionalData, &IsUnicode)) {
            if (IsUnicode) {
              Print (L"\t- Arguments: %s\n", BootOption->OptionalData);
            } else {
              AsciiPrint ("\t- Arguments: %a\n", BootOption->OptionalData);
            }
          }
        }
        FreePool(DevicePathTxt);
      DEBUG_CODE_END();

      OptionCount++;
    }
    BootOptionCount = OptionCount-1;

    // Display the hardcoded Boot entries
    for (Index = 0; Index < BootMainEntryCount; Index++) {
      Print(L"[%d] %s\n",OptionCount,BootMainEntries[Index]);
      OptionCount++;
    }

    // Request the boot entry from the user
    BootOptionSelected = 0;
    while (BootOptionSelected == 0) {
      Print(L"Start: ");
      Status = GetHIInputInteger (&BootOptionSelected);
      if (EFI_ERROR(Status) || (BootOptionSelected == 0) || (BootOptionSelected > OptionCount)) {
        Print(L"Invalid input (max %d)\n",(OptionCount-1));
        BootOptionSelected = 0;
      }
    }

    // Start the selected entry
    if (BootOptionSelected > BootOptionCount) {
      // Start the hardcoded entry
      Status = BootMainEntries[BootOptionSelected - BootOptionCount - 1].Callback (&BootOptionsList);
    } else {
      // Find the selected entry from the Boot#### list
      Index = 1;
      for (Entry = GetFirstNode (&BootOptionsList);
           !IsNull (&BootOptionsList,Entry);
           Entry = GetNextNode (&BootOptionsList,Entry)
           )
      {
        if (Index == BootOptionSelected) {
          BootOption = LOAD_OPTION_FROM_LINK(Entry);
          break;
        }
        Index++;
      }

      Status = BootOptionStart (BootOption);
    }
  }
  // Should never go here
}
예제 #29
0
파일: EfiFileLib.c 프로젝트: M1cha/edk2
/**
Open a device named by PathName. The PathName includes a device name and
path separated by a :. See file header for more details on the PathName
syntax. There is no checking to prevent a file from being opened more than
one type.

SectionType is only used to open an FV. Each file in an FV contains multiple
sections and only the SectionType section is opened.

For any file that is opened with EfiOpen() must be closed with EfiClose().

@param  PathName    Path to parse to open
@param  OpenMode    Same as EFI_FILE.Open()
@param  SectionType Section in FV to open.

@return NULL  Open failed
@return Valid EFI_OPEN_FILE handle

**/
EFI_OPEN_FILE *
EfiOpen (
  IN        CHAR8               *PathName,
  IN  CONST UINT64              OpenMode,
  IN  CONST EFI_SECTION_TYPE    SectionType
  )
{
  EFI_STATUS                Status;
  EFI_OPEN_FILE             *File;
  EFI_OPEN_FILE             FileData;
  UINTN                     StrLen;
  UINTN                     FileStart;
  UINTN                     DevNumber = 0;
  EFI_OPEN_FILE_GUARD       *GuardFile;
  BOOLEAN                   VolumeNameMatch;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     Size;
  EFI_IP_ADDRESS            Ip;
  CHAR8                     *CwdPlusPathName;
  UINTN                     Index;
  EFI_SECTION_TYPE          ModifiedSectionType;

  EblUpdateDeviceLists ();

  File = &FileData;
  ZeroMem (File, sizeof (EFI_OPEN_FILE));

  StrLen = AsciiStrSize (PathName);
  if (StrLen <= 1) {
    // Smallest valid path is 1 char and a null
    return NULL;
  }

  for (FileStart = 0; FileStart < StrLen; FileStart++) {
    if (PathName[FileStart] == ':') {
      FileStart++;
      break;
    }
  }

  //
  // Matching volume name has precedence over handle based names
  //
  VolumeNameMatch = EblMatchVolumeName (PathName, FileStart, &DevNumber);
  if (!VolumeNameMatch) {
    if (FileStart == StrLen) {
      // No Volume name or device name, so try Current Working Directory
      if (gCwd == NULL) {
        // No CWD
        return NULL;
      }

      // We could add a current working directory concept
      CwdPlusPathName = AllocatePool (AsciiStrSize (gCwd) + AsciiStrSize (PathName));
      if (CwdPlusPathName == NULL) {
        return NULL;
      }

      if ((PathName[0] == '/') || (PathName[0] == '\\')) {
        // PathName starts in / so this means we go to the root of the device in the CWD.
        CwdPlusPathName[0] = '\0';
        for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
          CwdPlusPathName[FileStart] = gCwd[FileStart];
          if (gCwd[FileStart] == ':') {
            FileStart++;
            CwdPlusPathName[FileStart] = '\0';
            break;
          }
        }
      } else {
        AsciiStrCpy (CwdPlusPathName, gCwd);
        StrLen = AsciiStrLen (gCwd);
        if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
          AsciiStrCat (CwdPlusPathName, "\\");
        }
      }

      AsciiStrCat (CwdPlusPathName, PathName);
      if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
        // Extra error check to make sure we don't recurse and blow stack
        return NULL;
      }

      File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
      FreePool (CwdPlusPathName);
      return File;
    }

    DevNumber = EblConvertDevStringToNumber ((CHAR8 *)PathName);
  }

  File->DeviceName = AllocatePool (StrLen);
  AsciiStrCpy (File->DeviceName, PathName);
  File->DeviceName[FileStart - 1] = '\0';
  File->FileName = &File->DeviceName[FileStart];
  if (File->FileName[0] == '\0') {
    // if it is just a file name use / as root
    File->FileName = "\\";
  }

  //
  // Use best match algorithm on the dev names so we only need to look at the
  // first few charters to match the full device name. Short name forms are
  // legal from the caller.
  //
  Status = EFI_SUCCESS;
  if (*PathName == 'f' || *PathName == 'F' || VolumeNameMatch) {
    if (PathName[1] == 's' || PathName[1] == 'S' || VolumeNameMatch) {
      if (DevNumber >= mFsCount) {
        goto ErrorExit;
      }
      File->Type = EfiOpenFileSystem;
      File->EfiHandle = mFs[DevNumber];
      Status = EblFileDevicePath (File, &PathName[FileStart], OpenMode);

    } else if (PathName[1] == 'v' || PathName[1] == 'V') {
      if (DevNumber >= mFvCount) {
        goto ErrorExit;
      }
      File->Type = EfiOpenFirmwareVolume;
      File->EfiHandle = mFv[DevNumber];

      if ((PathName[FileStart] == '/') || (PathName[FileStart] == '\\')) {
        // Skip leading / as its not really needed for the FV since no directories are supported
        FileStart++;
      }

      // Check for 2nd :
      ModifiedSectionType = SectionType;
      for (Index = FileStart; PathName[Index] != '\0'; Index++) {
        if (PathName[Index] == ':') {
          // Support fv0:\DxeCore:0x10
          // This means open the PE32 Section of the file
          ModifiedSectionType = (EFI_SECTION_TYPE)AsciiStrHexToUintn (&PathName[Index + 1]);
          PathName[Index] = '\0';
        }
      }
      File->FvSectionType = ModifiedSectionType;
      Status = EblFvFileDevicePath (File, &PathName[FileStart], ModifiedSectionType);
    }
  } else if ((*PathName == 'A') || (*PathName == 'a')) {
    // Handle a:0x10000000:0x1234 address form a:ADDRESS:SIZE
    File->Type = EfiOpenMemoryBuffer;
    // 1st colon is at PathName[FileStart - 1]
    File->Buffer = (VOID *)AsciiStrHexToUintn (&PathName[FileStart]);

    // Find 2nd colon
    while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
      FileStart++;
    }

    // If we ran out of string, there's no extra data
    if (PathName[FileStart] == '\0') {
      File->Size = 0;
    } else {
      File->Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
    }

    // if there's no number after the second colon, default
    // the end of memory
    if (File->Size == 0) {
      File->Size =  (UINTN)(0 - (UINTN)File->Buffer);
    }

    File->MaxPosition = File->Size;
    File->BaseOffset = (UINTN)File->Buffer;

  } else if (*PathName== 'l' || *PathName == 'L') {
    if (DevNumber >= mLoadFileCount) {
      goto ErrorExit;
    }
    File->Type = EfiOpenLoadFile;
    File->EfiHandle = mLoadFile[DevNumber];

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiLoadFileProtocolGuid, (VOID **)&File->LoadFile);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }
    File->DevicePath = DuplicateDevicePath (DevicePath);

  } else if (*PathName == 'b' || *PathName == 'B') {
    // Handle b#:0x10000000:0x1234 address form b#:ADDRESS:SIZE
    if (DevNumber >= mBlkIoCount) {
      goto ErrorExit;
    }
    File->Type = EfiOpenBlockIo;
    File->EfiHandle = mBlkIo[DevNumber];
    EblFileDevicePath (File, "", OpenMode);

    // 1st colon is at PathName[FileStart - 1]
    File->DiskOffset = AsciiStrHexToUintn (&PathName[FileStart]);

    // Find 2nd colon
    while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
      FileStart++;
    }

    // If we ran out of string, there's no extra data
    if (PathName[FileStart] == '\0') {
      Size = 0;
    } else {
      Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
    }

    // if a zero size is passed in (or the size is left out entirely),
    // go to the end of the device.
    if (Size == 0) {
      File->Size = File->Size - File->DiskOffset;
    } else {
      File->Size = Size;
    }

    File->MaxPosition = File->Size;
    File->BaseOffset = File->DiskOffset;
  } else if ((*PathName) >= '0' && (*PathName <= '9')) {

    // Get current IP address
    Status = EblGetCurrentIpAddress (&Ip);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Device IP Address is not configured.\n");
      goto ErrorExit;
    }


    // Parse X.X.X.X:Filename, only support IPv4 TFTP for now...
    File->Type = EfiOpenTftp;
    File->IsDirty = FALSE;
    File->IsBufferValid = FALSE;

    Status = ConvertIpStringToEfiIp (PathName, &File->ServerIp);
  }

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  GuardFile = (EFI_OPEN_FILE_GUARD *)AllocateZeroPool (sizeof (EFI_OPEN_FILE_GUARD));
  if (GuardFile == NULL) {
    goto ErrorExit;
  }

  GuardFile->Header = EFI_OPEN_FILE_GUARD_HEADER;
  CopyMem (&(GuardFile->File), &FileData, sizeof (EFI_OPEN_FILE));
  GuardFile->Footer = EFI_OPEN_FILE_GUARD_FOOTER;

  return &(GuardFile->File);

ErrorExit:
  FreePool (File->DeviceName);
  return NULL;
}
예제 #30
0
파일: EfiFileLib.c 프로젝트: M1cha/edk2
EFI_STATUS
EfiCopyFile (
  IN        CHAR8               *DestinationFile,
  IN        CHAR8               *SourceFile
  )
{
  EFI_OPEN_FILE *Source      = NULL;
  EFI_OPEN_FILE *Destination = NULL;
  EFI_STATUS    Status       = EFI_SUCCESS;
  VOID          *Buffer      = NULL;
  UINTN         Size;
  UINTN         Offset;
  UINTN         Chunk = FILE_COPY_CHUNK;

  Source = EfiOpen (SourceFile, EFI_FILE_MODE_READ, 0);
  if (Source == NULL) {
    AsciiPrint("Source file open error.\n");
    Status = EFI_NOT_FOUND;
    goto Exit;
  }

  Destination = EfiOpen (DestinationFile, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
  if (Destination == NULL) {
    AsciiPrint("Destination file open error.\n");
    Status = EFI_NOT_FOUND;
    goto Exit;
  }

  Buffer = AllocatePool(FILE_COPY_CHUNK);
  if (Buffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  Size = EfiTell(Source, NULL);

  for (Offset = 0; Offset + FILE_COPY_CHUNK <= Size; Offset += Chunk) {
    Chunk = FILE_COPY_CHUNK;

    Status = EfiRead(Source, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Read file error %r\n", Status);
      goto Exit;
    }

    Status = EfiWrite(Destination, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Write file error %r\n", Status);
      goto Exit;
    }
  }

  // Any left over?
  if (Offset < Size) {
    Chunk = Size - Offset;

    Status = EfiRead(Source, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Read file error\n");
      goto Exit;
    }

    Status = EfiWrite(Destination, Buffer, &Chunk);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Write file error\n");
      goto Exit;
    }
  }

Exit:
  if (Source != NULL) {
    Status = EfiClose(Source);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Source close error");
    }
  }

  if (Destination != NULL) {
    Status = EfiClose(Destination);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Destination close error");
    }
  }

  if (Buffer != NULL) {
    FreePool(Buffer);
  }

  return Status;
}