如何以编程方式使用参数启动 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)。
我正在使用 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)。