UEFI LoadImage挂起 [英] UEFI LoadImage hangs

查看:236
本文介绍了UEFI LoadImage挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究使用Bootservices函数LoadImage从内存中加载UEFI应用程序映像.函数参数为:

I am looking at using Bootservices function LoadImage to load a UEFI application image from memory. Function parameters are:

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
  );

我的内存中有源缓冲区,并装有要加载的PE/COFF映像.

I have sourcebuffer in memory and populated with the PE/COFF image to load.

我将其传递到SourceBuffer下,并将DevicePath设置为以下内容:

I pass that in under SourceBuffer and set DevicePath to the following:

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.我是否错误地配置了路径,以至于我永远不会退出下面的路径?

When I call load image the application hangs. I have set up visual studio to allow me to debug UEFI EDK2 source and have isolated where i'm stuck. Below is the EDK2 call that I appear to be stuck in. DevicePath is set to the mempath I setup above. Am I configuring my path incorrectly such that I never exit the below?

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调用堆栈

For more context this is the UDK callstack of where i'm stuck

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

推荐答案

找到了我的答案,在这里与其他人分享:

Found my answer, sharing here for others:

我基于grub的原始mempath:

I based my original mempath off of the grub source:http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/loader/arm64/linux.c?id=7a210304ebfd6d704b4fc08fe496a0c417441879#n249

我将端点的类型更改为实例,即标头的大小字段.我现在正确退出循环.我的原始标头具有整个结构的大小,因此我认为,当尝试迭代到下一个端点时,它的结尾处是无效的,而不是转到我的正确第二个元素.这是我用的:

I changed the type of end point to instance, the size field of the header. I properly exit the loop now. My original header had the size of the entire structure, so I believe when trying to iterate to the next endpoint it was winding up with an invalid one, instead of going to my correct second element. Here is what I used:

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);

这篇关于UEFI LoadImage挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆