繁体   English   中英

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

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

我正在使用 EDKII 编写 UEFI 模块。 我希望此模块使用参数加载和启动 UEFI shell(以使用其命令行功能)。 到目前为止,我有以下代码,它成功加载并启动了 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;
}

我在加载图像后尝试访问 EFI_SHELL_PARAMETERS_PROTOCOL 但在启动它之前,我认为我可以从那里手动更改参数,但似乎当时尚未安装协议(即使它在 UEFI Shell 规范中说在调用 StartImage 之前安装协议)。

LoadedImage 协议包含两个成员变量,可以直接访问它们以设置指向命令行的指针和以字节为单位的命令行大小。

UINT32 LoadOptionsSize;
VOID *LoadOptions;

获取代码中已有的 LoadedImage 协议后,只需使用 ImageInfo 指针设置这些字段。

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

加载选项的解释取决于应用程序。 我相信 Shell 将其视为 Unicode 字符串(UCS-2)。

暂无
暂无

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

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