Как ждать сетевой пакет с помощью простой сети GNU-EFI
Я пытаюсь использовать простой сетевой протокол EFI:
http://wiki.phoenix.com/wiki/index.php/EFI_SIMPLE_NETWORK_PROTOCOL
ждать входящего пакета Ethernet. Однако, используя 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 (ссылка выше) и на спецификации документа UEFI на 2899 страницах версии 2.7.
Несмотря на мой лучший поиск в Google, я не могу найти примеров использования WaitForPacket в приложении GNU-EFI.
Я попытался запустить и инициализировать сетевое оборудование, которое кажется необходимым для QEMU, но не для реального оборудования. Я также попытался установить аппаратный режим в случайный режим, используя функцию ReceiveFilters() и широковещательную рассылку, но это тоже не имело значения.
Есть идеи??