0

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

メモリにソースバッファがあり、ロードする 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);

load image を呼び出すと、アプリケーションがハングします。UEFI EDK2 ソースをデバッグできるように Visual Studio をセットアップし、行き詰まった場所を分離しました。以下は、スタックしているように見える 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
4

1 に答える 1

1

私の答えを見つけて、他の人のためにここで共有してください:

元の mempath は grub ソースに基づいています。

エンドポイントのタイプをヘッダーのサイズ フィールドであるインスタンスに変更しました。ループを適切に終了します。元のヘッダーには構造全体のサイズがあったため、次のエンドポイントに反復しようとすると、正しい 2 番目の要素に移動するのではなく、無効なエンドポイントになってしまったと思います。これが私が使用したものです:

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);
于 2015-07-10T20:17:32.023 に答える