我正在开发一个 EFI 应用程序来加载 NTFS 驱动程序 (ntfs_x64.efi)。当我使用“load ntfs_x64.efi”命令从 EFI shell 加载驱动程序时,它工作得很好。但是,当我尝试从 EFI 应用程序中以编程方式加载驱动程序时,它会加载,但类型和 #D 未分配。
DRV |版本 |类型 | CFG |诊断 | #D | #C |司机姓名 |图片名称 | 工作(外壳) 在此输入图片描述 不工作(EFI 应用程序) 在此输入图片描述
如果您能提供有关如何解决此问题的任何见解或建议,我将不胜感激。
EFI_STATUS
EFIAPI
LoadNtfsDriver(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS Status;
EFI_HANDLE LoadedImageHandle;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN ExitDataSize = 4*1024;
CHAR16 *ExitData = NULL;
// Allocate memory for ExitData
ExitData = AllocatePool(ExitDataSize);
if (ExitData == NULL) {
Print(L"Failed to allocate memory for ExitData.\n");
return EFI_OUT_OF_RESOURCES;
}
Print(L"Memory allocated\n");
// Get the Loaded Image Protocol for the current image to access its device handle
Status = gBS->OpenProtocol(
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR(Status))
{
Print(L"Failed to get LoadedImageProtocol: %r\n", Status);
return Status;
}
// Create a device path for the NTFS driver file
DevicePath = FileDevicePath(LoadedImage->DeviceHandle, NTFS_DRIVER_PATH);
if (DevicePath == NULL)
{
Print(L"Failed to create device path for %s\n", NTFS_DRIVER_PATH);
return EFI_NOT_FOUND;
}
// Load the NTFS driver (ntfs_x64.efi)
Status = gBS->LoadImage(
FALSE, // Not a Boot Image
ImageHandle, // Parent image handle
DevicePath, // Path to the NTFS driver
NULL, // Optional source buffer
0, // Size of the source buffer
&LoadedImageHandle // Image handle for the loaded driver
);
if (EFI_ERROR(Status))
{
Print(L"Failed to load %s: %r\n", NTFS_DRIVER_PATH, Status);
FreePool(DevicePath);
return Status;
}
Print(L"%s loaded successfully.\n", NTFS_DRIVER_PATH);
Print(L"Status: %r\n", Status);
// Start the NTFS driver
Status = gBS->StartImage(
LoadedImageHandle,
&ExitDataSize, // Optional exit data size
&ExitData // Optional exit data
);
if (EFI_ERROR(Status))
{
Print(L"Failed to start %s: %r\n", NTFS_DRIVER_PATH, Status);
}
else
{
Print(L"%s started successfully.\n", NTFS_DRIVER_PATH);
Print(L"Status: %r\n", Status);
Print(L"Exit Data: %s\n", ExitData);
}
// Free allocated device path memory
FreePool(DevicePath);
return EFI_SUCCESS;
}
我将驱动程序连接到磁盘 IO 协议的所有句柄,问题得到解决。
EFI_STATUS
EFIAPI
LoadNtfsDriver(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_STATUS Status;
EFI_HANDLE LoadedImageHandle;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINTN ExitDataSize = 4*1024;
CHAR16 *ExitData = NULL;
Status = gBS->OpenProtocol(
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage,
ImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (EFI_ERROR(Status))
{
Print(L"Failed to get LoadedImageProtocol: %r\n", Status);
return Status;
}
DevicePath = FileDevicePath(LoadedImage->DeviceHandle, NTFS_DRIVER_PATH);
if (DevicePath == NULL)
{
Print(L"Failed to create device path for %s\n", NTFS_DRIVER_PATH);
return EFI_NOT_FOUND;
}
Status = gBS->LoadImage(
FALSE, // Not a Boot Image
ImageHandle, // Parent image handle
DevicePath, // Path to the NTFS driver
NULL, // Optional source buffer
0, // Size of the source buffer
&LoadedImageHandle // Image handle for the loaded driver
);
if (EFI_ERROR(Status))
{
Print(L"Failed to load %s: %r\n", NTFS_DRIVER_PATH, Status);
FreePool(DevicePath);
return Status;
}
Print(L"%s loaded successfully.\n", NTFS_DRIVER_PATH);
Print(L"Status: %r\n", Status);
// Start the NTFS driver
Status = gBS->StartImage(
LoadedImageHandle,
&ExitDataSize, // Optional exit data size
&ExitData // Optional exit data
);
if (EFI_ERROR(Status))
{
Print(L"Failed to start %s: %r\n", NTFS_DRIVER_PATH, Status);
}
else
{
Print(L"%s started successfully.\n", NTFS_DRIVER_PATH);
Print(L"Status: %r\n", Status);
Print(L"Exit Data: %s\n", ExitData);
}
EFI_HANDLE *HandleBuffer;
UINTN HandleCount;
UINTN Index;
// Locate all handles supporting the Disk I/O protocol
Status = gBS->LocateHandleBuffer(
ByProtocol,
&gEfiDiskIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer);
if (EFI_ERROR(Status)) {
Print(L"Failed to locate Disk IO handles: %r\n", Status);
return Status;
}
for (Index = 0; Index < HandleCount; Index++) {
// Attempt to connect the controller for each handle
Status = gBS->ConnectController(
HandleBuffer[Index],
NULL,
NULL,
TRUE);
if (EFI_ERROR(Status)) {
Print(L"Failed to connect controller for handle %d: %r\n", Index, Status);
} else {
Print(L"Controller connected for handle %d.\n", Index);
}
}
if (HandleBuffer) {
FreePool(HandleBuffer);
}
// Free allocated device path memory
FreePool(DevicePath);
return EFI_SUCCESS;
}