在SNP层级实现的驱动及源码大概位置(代码所在EDK目录:edk2_code\NetworkPkg\SnpDxe\Snp.c)
/**
Start this driver on ControllerHandle. This service is called by the
EFI boot service ConnectController(). In order to make
drivers as small as possible, there are a few calling restrictions for
this service. ConnectController() must follow these
calling restrictions. If any other agent wishes to call Start() it
must also follow these calling restrictions.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to bind driver to.
@param RemainingDevicePath Optional parameter use to pick a specific child
device to start.
@retval EFI_SUCCESS This driver is added to ControllerHandle
@retval EFI_DEVICE_ERROR This driver could not be started due to a device error
@retval other This driver does not support this device
/
EFI_STATUS
EFIAPI
SimpleNetworkDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
XXXXXX
XXXXXX
//
// OK, we like this UNDI, and we know snp is not already there on this handle
// Allocate and initialize a new simple network protocol structure.
//
Status = PciIo->AllocateBuffer (
PciIo,
AllocateAnyPages,
EfiBootServicesData,
SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
&Address,
0
);
if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_NET, “\nCould not allocate SNP_DRIVER structure.\n”));
goto NiiError;
}
Snp = (SNP_DRIVER *) (UINTN) Address;
ZeroMem (Snp, sizeof (SNP_DRIVER));
Snp->PciIo = PciIo;
Snp->Signature = SNP_DRIVER_SIGNATURE;
EfiInitializeLock (&Snp->Lock, TPL_NOTIFY);
Snp->Snp.Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
这下边是SNP协议驱动实现部分,有兴趣可以详细看下。
Snp->Snp.Start = SnpUndi32Start;
Snp->Snp.Stop = SnpUndi32Stop;
Snp->Snp.Initialize = SnpUndi32Initialize;
Snp->Snp.Reset = SnpUndi32Reset;
Snp->Snp.Shutdown = SnpUndi32Shutdown;
Snp->Snp.ReceiveFilters = SnpUndi32ReceiveFilters;
Snp->Snp.StationAddress = SnpUndi32StationAddress;
Snp->Snp.Statistics = SnpUndi32Statistics;
Snp->Snp.MCastIpToMac = SnpUndi32McastIpToMac;
Snp->Snp.NvData = SnpUndi32NvData;
Snp->Snp.GetStatus = SnpUndi32GetStatus;
Snp->Snp.Transmit = SnpUndi32Transmit;
Snp->Snp.Receive = SnpUndi32Receive;
Snp->Snp.WaitForPacket = NULL;
底层采用的循环缓冲区
Snp->RecycledTxBuf = AllocatePool (sizeof (UINT64) * SNP_TX_BUFFER_INCREASEMENT);
if (Snp->RecycledTxBuf == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Error_DeleteSNP;
}
Snp->MaxRecycledTxBuf = SNP_TX_BUFFER_INCREASEMENT;
Snp->RecycledTxBufCount = 0;