简体   繁体   English

如何以编程方式使用参数启动 UEFI shell?

[英]How do I start UEFI shell with parameters programmatically?

I'm using EDKII to write a UEFI module.我正在使用 EDKII 编写 UEFI 模块。 I want this module to load and start UEFI shell with parameters (to use its command lines capabilities).我希望此模块使用参数加载和启动 UEFI shell(以使用其命令行功能)。 So far I have the following code, which successfully loads and starts the UEFI shell, but I can't seem to figure out how to start it with parameters.到目前为止,我有以下代码,它成功加载并启动了 UEFI shell,但我似乎无法弄清楚如何使用参数启动它。

EFI_STATUS
LoadAndStartShell (
  IN EFI_HANDLE        ImageHandle
  )
{
  UINTN NumHandles;
  UINTN Index;
  EFI_HANDLE *SFS_Handles;
  EFI_HANDLE AppImageHandle = NULL;
  EFI_STATUS Status = EFI_SUCCESS;
  EFI_BLOCK_IO_PROTOCOL *BlkIo;
  CONST CHAR16 *FileName = L"Shell.efi";
  EFI_DEVICE_PATH_PROTOCOL *FilePath;
  EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;
  UINTN ExitDataSize;

  Status = gBS->LocateHandleBuffer(
          ByProtocol,
          &gEfiSimpleFileSystemProtocolGuid,
          NULL,
          &NumHandles,
          &SFS_Handles);

  if (Status != EFI_SUCCESS) {
      Print(L"Could not find handles - %r\n", Status);
      return Status;
  }

  for (Index = 0; Index < NumHandles; Index++) {
      Status = gBS->OpenProtocol(
              SFS_Handles[Index],
              &gEfiSimpleFileSystemProtocolGuid,
              (VOID**) &BlkIo,
              ImageHandle,
              NULL,
              EFI_OPEN_PROTOCOL_GET_PROTOCOL
              );
  
      if (Status != EFI_SUCCESS) {
          Print(L"Protocol is not supported - %r\n", Status);
          return Status;
      }
  
      FilePath = FileDevicePath(SFS_Handles[Index], FileName);
      Status = gBS->LoadImage(
              FALSE, 
              ImageHandle, 
              FilePath, 
              (VOID*) NULL, 
              0, 
              &AppImageHandle);

      if (Status != EFI_SUCCESS) {
          Print(L"Could not load the image - %r\n", Status);
          continue;
      }

      Print(L"Loaded the image with success\n");
      Status = gBS->OpenProtocol(
              AppImageHandle,
              &gEfiLoadedImageProtocolGuid,
              (VOID**) &ImageInfo,
              ImageHandle,
              (VOID*) NULL,
              EFI_OPEN_PROTOCOL_GET_PROTOCOL
              );

      Print(L"ImageInfo opened\n");


      if (!EFI_ERROR(Status)) {
          Print(L"ImageSize = %d\n", ImageInfo->ImageSize);
      }

      Print(L"Image start:\n");
      Status = gBS->StartImage(AppImageHandle, &ExitDataSize, (CHAR16**) NULL);
      if (Status != EFI_SUCCESS) {
          Print(L"Could not start the image - %r %x\n", Status, Status);
          Print(L"Exit data size: %d\n", ExitDataSize);
          continue;
      }
  return Status;
  }
  return Status;
}

I tried accessing the EFI_SHELL_PARAMETERS_PROTOCOL after loading the image but before starting it, thinking I could manually change the parameters from there, but it seems like the protocol isn't installed yet at that point (even though it says at the UEFI Shell Specification that the protocol is installed before StartImage is called).我在加载图像后尝试访问 EFI_SHELL_PARAMETERS_PROTOCOL 但在启动它之前,我认为我可以从那里手动更改参数,但似乎当时尚未安装协议(即使它在 UEFI Shell 规范中说在调用 StartImage 之前安装协议)。

The LoadedImage protocol contains two member variables that can be accessed directly to set the pointer to the command line and the size in bytes of the command line. LoadedImage 协议包含两个成员变量,可以直接访问它们以设置指向命令行的指针和以字节为单位的命令行大小。

UINT32 LoadOptionsSize;
VOID *LoadOptions;

After getting the LoadedImage protocol which you already have in your code, just use the ImageInfo pointer to set these fields.获取代码中已有的 LoadedImage 协议后,只需使用 ImageInfo 指针设置这些字段。

ImageInfo->LoadOptions = cmdline;
ImageInfo->LoadOptionsSize = cmdline_size;

The interpretation of the load options is up to the application.加载选项的解释取决于应用程序。 I believe that the Shell treats it as a Unicode string (UCS-2).我相信 Shell 将其视为 Unicode 字符串(UCS-2)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM