I am trying to obtain an IP via DHCP in UEFI. In testing this, I'm using QEMU (version 8.0.0). I have a shell command that I've incorporated into my build of OVMF for testing this. Essentially, what I'm doing is
#include <Uefi.h>
#include <Library/ShellLib.h>
#include <Protocol/Dhcp4.h>
#include <Protocol/ServiceBinding.h>
#include <Protocol/SimpleNetwork.h>
EFI_STATUS
EFIAPI
GetIpAddress(VOID)
{
EFI_SERVICE_BINDING_PROTOCOL *DhcpBinding = NULL;
EFI_STATUS Status;
Status = gBS->LocateProtocol(
&gEfiDhcp4ServiceBindingProtocolGuid,
NULL,
(VOID**)&DhcpBinding);
ShellPrintEx(-1, -1, L"Returned %r opening dhcp4 binding\n", Status);
return Status;
}
Whenever I try this, I see, "Returned Not Found opening dhcp4 binding". I have confirmed that DHCP4 is included in the OVMF build I'm using. The QEMU documentation indicates that a network device is present by default. This is confirmed when I start the VM with a disk that has Linux installed and let it boot. I can use a network.
The defaults show, from the UEFI shell, that there is an iPXE 82754l (VID:8086 and DID:10D3) device. When I use ifconfig -l
from the UEFI shell, nothing is returned.
I'm now drawing from this response in helping me get the right "formula". Prior to this, I was just using the UEFI spec. (For reference, primarily from this section)
At one point, I tried getting the Simple Network Protocol then starting the interface and then configuring it because it sounded like that was part of the process. Trying that I was able to locate that protocol, start the NIC and Initialize it. Though I did manage that, I'm still unable to use gBS->LocateProtocol()
to find the DHCP4 Service Binding Protocol.
What might I be missing? That could be with my QEMU instance, or what I'm trying to do in UEFI. Are there elements I might be missing?
The build of OVMF
$ . ./edksetup.sh
$ build --platform OvmfPkg/OvmfPkgX64.dsc --arch X64 --tagname GCC --target DEBUG
(Please note that the use of all but --platform
I have set in my Conf/target.txt
file.) I have tried a variety of differences to this. Some of them are (keeping in mind that I have Conf/target.txt configured):
$ build --platform OvmfPkg/OvmfPkgX64.dsc --define NETWORK_ENABLE=TRUE
$ build --platform OvmfPkg/OvmfPkgX64.dsc --define NETWORK_ENABLE --define NETWORK_PXE_BOOT_ENABLE=FALSE
That last one was a trial based on this Intel doc says, "As of UEFI 2.1, the PXE and IP-based network stacks cannot be loaded or operate simultaneously." This didn't help anything though.
I am regularly calling qemu with:
$ qemu-system-x86_64 -machine q35,accel=kvm -m 2G \
-smp cpus=2 -cpu Nehalem-v2 \
-debugcon file:qemu_debug.log -global isa-debugcon.iobase=0x402 \
-L /path/to/edk2/build/ -bios /path/to/edk2/build/OVMF.fd
I'm not using any other arguments for a disk image. I am interested only in UEFI development so I'm working in the shell.
Taking your (@MiSimon) last comment to heart, I install the Rocky OVMF package and did the following:
$ cp /usr/share/edk2/ovmf/OVMF_CODE.fd .
$ qemu-start-x86_64 \
-machine q35,accel=kvm -m 2G \
-smp cpus=2 -cpu Nehalem-v2 \
-pflash ./OVMF_CODE.fd
I was unable to use the -L -bios
options that I usually use in my start-vm.sh
script. After successfully starting OVMF with basically the same options (except for -pflash
vs. -L .. -bios ..
, I'm guessing that I'm misusing the images that I'm building. Looking forward to your insight.
The builds of OVMF from Rocky 9 work. Using the source RPM for that I found that the RPM uses the EDK2 tag edk2-stable202311
(and the applies a plethora patches). Using that as a theory I have found that I can get the network stack to load as expected with tags edk2-stable202311
(without any patches) and edk2-stable202402
. However, beginning with tag edk2-stable202405
forward, the network stack is not loaded.
I learned this using the build as
$ build --platform OvmfPkg/OvmfPkgX64.dsc --arch X64 --tagname GCC --buildtarget DEBUG
And starting QEMU
$ qemu-system-x86_64 \
-machine q35,accel=kvm -m 2G \
-smp cpus=2 -cpu Nehalem-v2 \
-pflash /path/to/OVMF.fd
Using tag edk2-stable202402
those work, but with tag edk2-stable202405
it does not.
You need to enable the virtual RNG in QEMU by adding the -device virtio-rng-pci
parameter.
The SNP driver in the newer versions of EDK2/OvmgPkg has a DXE dependency on the RngProtocol. Since the RNG driver apparently cannot provide this protocol without the virtual RNG, the RngProtocol is missing, and the SNP driver is not dispatched.
In the earlier versions of EDK2/OvmgPkg the SNP driver has no DXE dependency on the RngProtocol and is therefore available without the additional option.