我尝试使用EFI简单网络协议:
http://wiki.phoenix.com/wiki/index.php/EFI_SIMPLE_NETWORK_PROTOCOL
等待传入的以太网数据包。但是,使用QEMU时,即使有传入的数据包,WaitForPacket事件也不会触发,而在实际硬件上,事件总是立即触发而不会有任何数据包到达。我可以在电线上看到我的样品包"使用tcpdump所以我相当自信我正在向它提供数据包。这是我的代码(归结为这个测试用例):
#include <efi.h>
#include <efilib.h>
EFI_HANDLE getNetHandle();
EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
InitializeLib(ImageHandle, SystemTable);
EFI_GUID snpguid = EFI_SIMPLE_NETWORK_PROTOCOL;
EFI_HANDLE netHandle = getNetHandle();
EFI_STATUS status;
EFI_SIMPLE_NETWORK* net_if_struct;
status = uefi_call_wrapper(BS->HandleProtocol, 3,
netHandle, &snpguid, &net_if_struct);
Print(L"Main: HandleProtocol status: %r\n", status);
Print(L"Main: WaitForPacket event: %x\n", net_if_struct->WaitForPacket);
EFI_EVENT waitEvents[1];
waitEvents[0] = net_if_struct->WaitForPacket;
UINTN eventTriggered;
status = uefi_call_wrapper(BS->WaitForEvent, 3,
1, waitEvents, &eventTriggered);
Print(L"Main: WaitForEvent status: %r, event triggered: %d\n", status, eventTriggered);
return EFI_SUCCESS;
}
EFI_HANDLE getNetHandle()
{
UINTN numHandles = 0;
EFI_HANDLE* handles = NULL;
EFI_GUID SimpleNetworkGUID = EFI_SIMPLE_NETWORK_PROTOCOL;
EFI_STATUS status = uefi_call_wrapper(BS->LocateHandleBuffer, 5,
ByProtocol, &SimpleNetworkGUID, NULL, &numHandles, &handles);
if (status != EFI_SUCCESS)
Print(L"getNetHandle: Failed to LocateHandleBuffer (%d)\n", status);
else
Print(L"getNetHandle: LocateHandleBuffer OK (%d handles)\n", numHandles);
EFI_HANDLE toReturn = NULL;
if (numHandles == 1)
{
toReturn = handles[0];
}
FreePool(handles);
return toReturn;
}
我尝试过的事情/证据/线索我有:
当这运行时,WaitForPacket事件打印行打印一个非空值,所以我假设EFI系统已经创建了一个事件并在EFI_SIMPLE_NETWORK结构中保持准备状态。
我尝试过另外一种方法,我需要创建一个事件并将其放在结构中,然后使用该事件等待,但它没有任何区别。
我有其他代码可以发送和接收数据包(只是),所以我认为我对网络句柄和接口结构的理解是合理的,我的EFI硬件和QEMU能够进行网络通信。
关于如何使用WaitForPacket的文档是不存在的,在某种程度上,感觉这应该是正常工作之一。我发现的文档位于Phoenix wiki(上面链接)和2899页UEFI规范文档2.7版。
尽管我用Google搜索最好,但我找不到在GNU-EFI应用程序中使用WaitForPacket的任何示例。
我已尝试启动和初始化网络硬件,这对QEMU来说似乎是必要的,但不是真正的硬件。我还尝试使用ReceiveFilters()将硬件设置为混杂模式并在其上进行广播,但这也没有任何区别。
任何想法??