예제 #1
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;
}
예제 #2
0
파일: EfiDevice.c 프로젝트: FishYu1222/edk2
/**
  Load a Firmware Volume (FV) into memory from a device. This causes drivers in
  the FV to be dispatched if the dependencies of the drivers are met.

  Argv[0] - "loadfv"
  Argv[1] - device name and path

  loadfv fs1:\Temp\Fv.Fv ; load an FV from the disk
  loadfv fv0:\FV         ; load an FV from an FV (not common)
  loadfv LoadFile0:      ; load an FV via a PXE boot

  @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
EblLoadFvCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                        Status;
  EFI_OPEN_FILE                     *File;
  VOID                              *FvStart;
  UINTN                             FvSize;
  EFI_HANDLE                        FvHandle;


  if (Argc < 2) {
    return EFI_INVALID_PARAMETER;
  }

  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (File->Type == EfiOpenMemoryBuffer) {
    // If it is a address just use it.
    Status = gDS->ProcessFirmwareVolume (File->Buffer, File->Size, &FvHandle);
  } else {
    // If it is a file read it into memory and use it
    Status = EfiReadAllocatePool (File, &FvStart, &FvSize);
    EfiClose (File);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = gDS->ProcessFirmwareVolume (FvStart, FvSize, &FvHandle);
    if (EFI_ERROR (Status)) {
      FreePool (FvStart);
    }
  }
  return Status;
}
예제 #3
0
파일: EfiDevice.c 프로젝트: FishYu1222/edk2
/**
  Load a file into memory and optionally jump to it. A load address can be
  specified or automatically allocated. A quoted command line can optionally
  be passed into the image.

  Argv[0] - "go"
  Argv[1] - Device Name:path for the file to load
  Argv[2] - Address to load to or '*' if the load address will be allocated
  Argv[3] - Optional Entry point to the image. Image will be called if present
  Argv[4] - "" string that will be passed as Argc & Argv to EntryPoint. Needs
            to include the command name

  go fv1:\EblCmdX  0x10000  0x10010 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX
    from FV1 to location 0x10000 and call the entry point at 0x10010 passing
    in "EblCmdX Arg2 Arg3 Arg4" as the arguments.

  go fv0:\EblCmdX  *  0x10 "EblCmdX Arg2 Arg3 Arg4"; - load EblCmdX from FS0
    to location allocated by this command and call the entry point at offset 0x10
    passing in "EblCmdX Arg2 Arg3 Arg4" as the arguments.

  go fv1:\EblCmdX  0x10000; Load EblCmdX to address 0x10000 and return

  @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
EblGoCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                    Status;
  EFI_OPEN_FILE                 *File;
  VOID                          *Address;
  UINTN                         Size;
  EBL_COMMMAND                  EntryPoint;
  UINTN                         EntryPointArgc;
  CHAR8                         *EntryPointArgv[MAX_ARGS];


  if (Argc <= 2) {
    // device name and laod address are 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;
  }

  EntryPoint  = (EBL_COMMMAND)((Argc > 3) ? (UINTN)AsciiStrHexToUintn (Argv[3]) : (UINTN)NULL);
  if (Argv[2][0] == '*') {
    // * Means allocate the buffer
    Status = EfiReadAllocatePool (File, &Address, &Size);

    // EntryPoint is relative to the start of the image
    EntryPoint = (EBL_COMMMAND)((UINTN)EntryPoint + (UINTN)Address);

  } else {
    Address = (VOID *)AsciiStrHexToUintn (Argv[2]);
    Size = File->Size;

    // File->Size for LoadFile is lazy so we need to use the tell to figure it out
    EfiTell (File, NULL);
    Status = EfiRead (File, Address, &Size);
  }

  if (!EFI_ERROR (Status)) {
    AsciiPrint ("Loaded %,d bytes to 0x%08x\n", Size, Address);

    if (Argc > 3) {
      if (Argc > 4) {
        ParseArguments (Argv[4], &EntryPointArgc, EntryPointArgv);
      } else {
        EntryPointArgc = 1;
        EntryPointArgv[0] = File->FileName;
      }

      Status = EntryPoint (EntryPointArgc, EntryPointArgv);
    }
  }

  EfiClose (File);
  return Status;
}
예제 #4
0
파일: EfiDevice.c 프로젝트: FishYu1222/edk2
/**
  Start an EFI image (PE32+ with EFI defined entry point).

  Argv[0] - "start"
  Argv[1] - device name and path
  Argv[2] - "" string to pass into image being started

  start fs1:\Temp\Fv.Fv "arg to pass" ; load an FV from the disk and pass the
                                      ; ascii string arg to pass to the image
  start fv0:\FV                       ; load an FV from an FV (not common)
  start LoadFile0:                    ; load an FV via a PXE boot

  @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
EblStartCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS                  Status;
  EFI_OPEN_FILE               *File;
  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
  EFI_HANDLE                  ImageHandle;
  UINTN                       ExitDataSize;
  CHAR16                      *ExitData;
  VOID                        *Buffer;
  UINTN                       BufferSize;
  EFI_LOADED_IMAGE_PROTOCOL   *ImageInfo;

  ImageHandle = NULL;

  if (Argc < 2) {
    return EFI_INVALID_PARAMETER;
  }

  File = EfiOpen (Argv[1], EFI_FILE_MODE_READ, 0);
  if (File == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DevicePath = File->DevicePath;
  if (DevicePath != NULL) {
    // check for device path form: blk, fv, fs, and loadfile
    Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);
  } else {
    // Check for buffer form: A0x12345678:0x1234 syntax.
    // Means load using buffer starting at 0x12345678 of size 0x1234.

    Status = EfiReadAllocatePool (File, &Buffer, &BufferSize);
    if (EFI_ERROR (Status)) {
      EfiClose (File);
      return Status;
    }
    Status = gBS->LoadImage (FALSE, gImageHandle, DevicePath, Buffer, BufferSize, &ImageHandle);

    FreePool (Buffer);
  }

  EfiClose (File);

  if (!EFI_ERROR (Status)) {
    if (Argc >= 3) {
      // Argv[2] is a "" string that we pass directly to the EFI application without the ""
      // We don't pass Argv[0] to the EFI Application (it's name) just the args
      Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&ImageInfo);
      ASSERT_EFI_ERROR (Status);

      ImageInfo->LoadOptionsSize = (UINT32)AsciiStrSize (Argv[2]);
      ImageInfo->LoadOptions     = AllocatePool (ImageInfo->LoadOptionsSize);
      AsciiStrCpy (ImageInfo->LoadOptions, Argv[2]);
    }

    // Transfer control to the EFI image we loaded with LoadImage()
    Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData);
  }

  return Status;
}