【UEFI基础】EDK网络框架(基础说明)

基础说明

UEFI中的网络框架大致如下:

【UEFI基础】EDK网络框架(基础说明)_第1张图片

红框部分是实现UEFI的EDK2开源项目中网络框架自带的实现,红框之外的部分需要网卡设备商提供驱动。UEFI下通常推荐使用最右边的形式,即网卡设备商提供实现了UNDI的网卡驱动。因此UEFI网络框架的另一个形式如下:

【UEFI基础】EDK网络框架(基础说明)_第2张图片

其中最底下UNDI部分并不在开源的EDK代码中,它代表的是网卡驱动,所以一般由网卡开发商来实现并提供出来供EDK代码集成。比如Intel的I350网卡驱动可以在Intel® 乙太網路介面卡 完整的驱动程序包下载到:

【UEFI基础】EDK网络框架(基础说明)_第3张图片

这里的zip压缩包包含了所有的Intel网卡驱动,其中有一部分就是在UEFI下使用的,如下所示:

【UEFI基础】EDK网络框架(基础说明)_第4张图片

这里的几个压缩包都是UEFI下的Intel网卡驱动源码,其中GigUndiDxe.zip可以用于初始化I350等网卡的,其它则是给更高速率的网卡使用的。

UNDI驱动提供的接口可以与SNP对接。而SNP及以上的部分在EDK中都有源码,它们是UEFI下的网络协议栈。另外关于安全部分(TLS或者HTTPS中的S)也可以认为是UEFI网络协议栈的一部分,虽然并不都在EDK开源代码中,但是也能够在其它地方找到对应的源码。

下面是一般的网络模型与UEFI网络模型的简单对比:

【UEFI基础】EDK网络框架(基础说明)_第5张图片

其实UEFI网络模型的大部分内容都与普通的TCP/IP网络模型一致,只不过多了一些UEFI特有的驱动,主要是MNP和SNP,而UNDI只是网卡在UEFI下的驱动而已。

代码说明

EDK代码中,可以在NetworkPkg目录下找到大部分的网络协议栈代码,以下是位于\NetworkPkg\NetworkComponents.dsc.inc(对应的EDK开源代码版本edk2-stable202211,不同的版本内容可能稍有差异)中描述的各个网络驱动:

!if $(NETWORK_ENABLE) == TRUE
  NetworkPkg/DpcDxe/DpcDxe.inf

  !if $(NETWORK_SNP_ENABLE) == TRUE
    NetworkPkg/SnpDxe/SnpDxe.inf
  !endif

  !if $(NETWORK_VLAN_ENABLE) == TRUE
    NetworkPkg/VlanConfigDxe/VlanConfigDxe.inf
  !endif

  NetworkPkg/MnpDxe/MnpDxe.inf

  !if $(NETWORK_IP4_ENABLE) == TRUE
    NetworkPkg/ArpDxe/ArpDxe.inf
    NetworkPkg/Dhcp4Dxe/Dhcp4Dxe.inf
    NetworkPkg/Ip4Dxe/Ip4Dxe.inf
    NetworkPkg/Udp4Dxe/Udp4Dxe.inf
    NetworkPkg/Mtftp4Dxe/Mtftp4Dxe.inf
  !endif

  !if $(NETWORK_IP6_ENABLE) == TRUE
    NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
    NetworkPkg/Ip6Dxe/Ip6Dxe.inf
    NetworkPkg/Udp6Dxe/Udp6Dxe.inf
    NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
  !endif

  NetworkPkg/TcpDxe/TcpDxe.inf
  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf

  !if $(NETWORK_TLS_ENABLE) == TRUE
    NetworkPkg/TlsDxe/TlsDxe.inf
    NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
  !endif

  !if ($(NETWORK_HTTP_BOOT_ENABLE) == TRUE) OR ($(NETWORK_HTTP_ENABLE) == TRUE)
    NetworkPkg/DnsDxe/DnsDxe.inf
    NetworkPkg/HttpDxe/HttpDxe.inf
    NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
  !endif

  !if $(NETWORK_HTTP_BOOT_ENABLE) == TRUE
    NetworkPkg/HttpBootDxe/HttpBootDxe.inf
  !endif

  !if $(NETWORK_ISCSI_ENABLE) == TRUE
    NetworkPkg/IScsiDxe/IScsiDxe.inf
  !endif
!endif

可以看到EDK支持IPv4和IPv6两个版本,不过目前BIOS下使用比较多的还是IPv4,后面的分析也主要针对IPv4版本。以上的协议,按照UEFI代码模型分类的话大部分都属于UEFI Driver Model。它们都会在DXE阶段安装类似如下的结构:

//
// Simple Network Protocol Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {
  SimpleNetworkDriverSupported,
  SimpleNetworkDriverStart,
  SimpleNetworkDriverStop,
  0xa,
  NULL,
  NULL
};

并在BDS阶段执行判断(xxxSupported)和执行具体实现(xxxStart),这种结构称为Driver Binding Protocol。

本文使用开源的EDK代码来具体说明UEFI网络协议栈的实现,可以在GitHub - tianocore/edk2: EDK II或者edk2: https://github.com/tianocore/edk2.git (gitee.com)下载到EDK源码,不过本文使用的测试代码来自edk2-beni: 用于学习和验证UEFI BIOS。 (gitee.com),使用该代码可以直接编译出在QEMU虚拟机上使用的BIOS,并可以使用它来测试UEFI网络代码。

另外,本文主要介绍的是UEFI中的网络协议实现代码,重点关注UEFI,而不是网络实现,所以对于UNDI中的网卡实现逻辑、网络协议的具体格式、网络数据包的具体解析等不会详细介绍。

你可能感兴趣的:(UEFI开发基础,网络,uefi)