UEFI LoadImage 挂起
UEFI LoadImage hangs
我正在考虑使用 Bootservices 函数 LoadImage 从内存中加载 UEFI 应用程序映像。函数参数为:
typedef
EFI_STATUS
LoadImage (
IN BOOLEAN BootPolicy,
IN EFI_HANDLE ParentImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN VOID *SourceBuffer OPTIONAL,
IN UINTN SourceSize,
OUT EFI_HANDLE *ImageHandle
);
我在内存中有 sourcebuffer 并填充了要加载的 PE/COFF 图像。
我将其传递到 SourceBuffer 下并将 DevicePath 设置为以下内容:
MEMMAP_DEVICE_PATH mempath[2];
mempath[0].Header.Type = HARDWARE_DEVICE_PATH;
mempath[0].Header.SubType = HW_MEMMAP_DP;
mempath[0].Header.Length[0] = (UINT8)sizeof(mempath);
mempath[0].Header.Length[1] = (UINT8)(sizeof(mempath)>> 8);
mempath[0].MemoryType = EfiLoaderCode;
mempath[0].StartingAddress = (UINT32)buff_ptr;
mempath[0].EndingAddress = (UINT32)(buff_ptr + BUFF_SIZE);
mempath[1].Header.Type = END_DEVICE_PATH_TYPE;
mempath[1].Header.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
mempath[1].Header.Length[0] = (UINT8)sizeof(EFI_DEVICE_PATH);
mempath[1].Header.Length[1] = (UINT8)(sizeof(EFI_DEVICE_PATH)>> 8);
当我调用加载图像时,应用程序挂起。我已经设置 visual studio 以允许我调试 UEFI EDK2 源代码并隔离了我卡住的地方。下面是我似乎卡在其中的 EDK2 调用。DevicePath 设置为我在上面设置的 mempath。我是否错误地配置了我的路径,以至于我永远不会退出下面的路径?
EFI_STATUS
EFIAPI
CoreLocateDevicePath (
IN EFI_GUID *Protocol,
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
OUT EFI_HANDLE *Device
)
{
......
EFI_DEVICE_PATH_PROTOCOL *SourcePath;
SourcePath = *DevicePath;
TmpDevicePath = SourcePath;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//I NEVER GET OUT OF THIS LOOP!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
while (!IsDevicePathEnd (TmpDevicePath)) {
if (IsDevicePathEndInstance (TmpDevicePath)) {
break;
}
TmpDevicePath = NextDevicePathNode (TmpDevicePath);
}
有关更多上下文,这是我卡住的地方的 UDK 调用堆栈
DxeCore.dll!CoreLocateDevicePath(GUID * Protocol, EFI_DEVICE_PATH_PROTOCOL * * DevicePath, void * * Device) Line 452 C
DxeCore.dll!CoreLoadImageCommon(unsigned char BootPolicy, void * ParentImageHandle, EFI_DEVICE_PATH_PROTOCOL * FilePath, void * SourceBuffer, unsigned int SourceSize, unsigned __int64 DstBuffer, unsigned int * NumberOfPages, void * * ImageHandle, unsigned __int64 * EntryPoint, unsigned int Attribute) Line 1089 C
DxeCore.dll!CoreLoadImage(unsigned char BootPolicy, void * ParentImageHandle, EFI_DEVICE_PATH_PROTOCOL * FilePath, void * SourceBuffer, unsigned int SourceSize, void * * ImageHandle) Line 1425 C
MyApplication.dll!efi_main(void * ImageHandle, EFI_SYSTEM_TABLE * SystemTable) Line 2588 C
找到我的答案,在这里分享给其他人:
我的原始内存路径基于 grub 源:http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/loader/arm64/linux.c?id=7a210304ebfd6d704b4fc08fe496a0c417441879#n249
我将端点的类型更改为实例,header 的大小字段。我现在正确退出循环。我原来的 header 具有整个结构的大小,所以我相信当尝试迭代到下一个端点时,它最终会得到一个无效的端点,而不是转到我正确的第二个元素。这是我使用的:
mempath[0].Header.Type = HARDWARE_DEVICE_PATH;
mempath[0].Header.SubType = HW_MEMMAP_DP;
mempath[0].Header.Length[0] = (UINT8)sizeof(MEMMAP_DEVICE_PATH);
mempath[0].Header.Length[1] = (UINT8)(sizeof(MEMMAP_DEVICE_PATH)>> 8);
mempath[0].MemoryType = EfiLoaderCode;
mempath[0].StartingAddress = (UINT32)buff_ptr;
mempath[0].EndingAddress = (UINT32)(buff_ptr + SIZEOF_HELLO_EFI);
mempath[1].Header.Type = END_DEVICE_PATH_TYPE;
mempath[1].Header.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
mempath[1].Header.Length[0] = (UINT8)sizeof(EFI_DEVICE_PATH);
mempath[1].Header.Length[1] = (UINT8)(sizeof(EFI_DEVICE_PATH)>> 8);
我正在考虑使用 Bootservices 函数 LoadImage 从内存中加载 UEFI 应用程序映像。函数参数为:
typedef
EFI_STATUS
LoadImage (
IN BOOLEAN BootPolicy,
IN EFI_HANDLE ParentImageHandle,
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN VOID *SourceBuffer OPTIONAL,
IN UINTN SourceSize,
OUT EFI_HANDLE *ImageHandle
);
我在内存中有 sourcebuffer 并填充了要加载的 PE/COFF 图像。
我将其传递到 SourceBuffer 下并将 DevicePath 设置为以下内容:
MEMMAP_DEVICE_PATH mempath[2];
mempath[0].Header.Type = HARDWARE_DEVICE_PATH;
mempath[0].Header.SubType = HW_MEMMAP_DP;
mempath[0].Header.Length[0] = (UINT8)sizeof(mempath);
mempath[0].Header.Length[1] = (UINT8)(sizeof(mempath)>> 8);
mempath[0].MemoryType = EfiLoaderCode;
mempath[0].StartingAddress = (UINT32)buff_ptr;
mempath[0].EndingAddress = (UINT32)(buff_ptr + BUFF_SIZE);
mempath[1].Header.Type = END_DEVICE_PATH_TYPE;
mempath[1].Header.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
mempath[1].Header.Length[0] = (UINT8)sizeof(EFI_DEVICE_PATH);
mempath[1].Header.Length[1] = (UINT8)(sizeof(EFI_DEVICE_PATH)>> 8);
当我调用加载图像时,应用程序挂起。我已经设置 visual studio 以允许我调试 UEFI EDK2 源代码并隔离了我卡住的地方。下面是我似乎卡在其中的 EDK2 调用。DevicePath 设置为我在上面设置的 mempath。我是否错误地配置了我的路径,以至于我永远不会退出下面的路径?
EFI_STATUS
EFIAPI
CoreLocateDevicePath (
IN EFI_GUID *Protocol,
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
OUT EFI_HANDLE *Device
)
{
......
EFI_DEVICE_PATH_PROTOCOL *SourcePath;
SourcePath = *DevicePath;
TmpDevicePath = SourcePath;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//I NEVER GET OUT OF THIS LOOP!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
while (!IsDevicePathEnd (TmpDevicePath)) {
if (IsDevicePathEndInstance (TmpDevicePath)) {
break;
}
TmpDevicePath = NextDevicePathNode (TmpDevicePath);
}
有关更多上下文,这是我卡住的地方的 UDK 调用堆栈
DxeCore.dll!CoreLocateDevicePath(GUID * Protocol, EFI_DEVICE_PATH_PROTOCOL * * DevicePath, void * * Device) Line 452 C
DxeCore.dll!CoreLoadImageCommon(unsigned char BootPolicy, void * ParentImageHandle, EFI_DEVICE_PATH_PROTOCOL * FilePath, void * SourceBuffer, unsigned int SourceSize, unsigned __int64 DstBuffer, unsigned int * NumberOfPages, void * * ImageHandle, unsigned __int64 * EntryPoint, unsigned int Attribute) Line 1089 C
DxeCore.dll!CoreLoadImage(unsigned char BootPolicy, void * ParentImageHandle, EFI_DEVICE_PATH_PROTOCOL * FilePath, void * SourceBuffer, unsigned int SourceSize, void * * ImageHandle) Line 1425 C
MyApplication.dll!efi_main(void * ImageHandle, EFI_SYSTEM_TABLE * SystemTable) Line 2588 C
找到我的答案,在这里分享给其他人:
我的原始内存路径基于 grub 源:http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/loader/arm64/linux.c?id=7a210304ebfd6d704b4fc08fe496a0c417441879#n249
我将端点的类型更改为实例,header 的大小字段。我现在正确退出循环。我原来的 header 具有整个结构的大小,所以我相信当尝试迭代到下一个端点时,它最终会得到一个无效的端点,而不是转到我正确的第二个元素。这是我使用的:
mempath[0].Header.Type = HARDWARE_DEVICE_PATH;
mempath[0].Header.SubType = HW_MEMMAP_DP;
mempath[0].Header.Length[0] = (UINT8)sizeof(MEMMAP_DEVICE_PATH);
mempath[0].Header.Length[1] = (UINT8)(sizeof(MEMMAP_DEVICE_PATH)>> 8);
mempath[0].MemoryType = EfiLoaderCode;
mempath[0].StartingAddress = (UINT32)buff_ptr;
mempath[0].EndingAddress = (UINT32)(buff_ptr + SIZEOF_HELLO_EFI);
mempath[1].Header.Type = END_DEVICE_PATH_TYPE;
mempath[1].Header.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
mempath[1].Header.Length[0] = (UINT8)sizeof(EFI_DEVICE_PATH);
mempath[1].Header.Length[1] = (UINT8)(sizeof(EFI_DEVICE_PATH)>> 8);