7

UEFI开发探索97 – EDK2模拟器搭建网络环境

 3 years ago
source link: http://yiiyee.cn/blog/2021/08/22/uefi%e5%bc%80%e5%8f%91%e6%8e%a2%e7%b4%a297-edk2%e6%a8%a1%e6%8b%9f%e5%99%a8%e6%90%ad%e5%bb%ba%e7%bd%91%e7%bb%9c%e7%8e%af%e5%a2%83/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

UEFI开发探索97 – EDK2模拟器搭建网络环境

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】

最近一段时间,很多网友问的问题都是和网络相关的。讨论的问题大部分是关于网络环境的搭建,有些现象我也没有遇到过。

在UEFI开发探索49中,介绍过在Nt32模拟器和真实环境中搭建UEFI网络环境。当时我使用的EDK2是UDK2018的版本。

随着EDK2版本的升级,原有的NT32模拟器(使用Nt32Pkg编译)已经取消了,随之替代的是EmulatorPkg。后者提供的功能更为全面,提供了32位和64位的模拟器,之前的博客中也曾经介绍过。

因此,本篇准备用EmulatorPkg编译的模拟器重新搭建网络测试环境。之前的模拟器使用Nt32Pkg编译,所以我取名为Nt32模拟器;现在的EmulatorPkg名字太长了,为方便行文,称之为EDK2模拟器了。

1 搭建EDK2开发环境

详细的搭建过程,可以参考UEFI开发探索22和57,这里简单描述本次的搭建过程。步骤如下:

1)工具安装

安装必要的开发工具,包括Visual Studio、Python、ASL和Nasm;

2)下载代码库

使用Git将EDK2的代码和StdLib的代码下载到本地。

在C盘新建目录edk202011,使用如下命令下载:

robin@robin-PC MINGW64 /c/edk202011
$ git clone --branch stable/202011 https://gitee.com/luobing4365/edk2.git
$ git clone https://gitee.com/luobing4365/edk2-libc.git

请注意,这里下载的地址是我的私有仓库,我把github上的edk2和edk2-libc的仓库同步到我在gitee上的仓库中了,方便自己下载。

不要按照我给的命令去下载,原始的仓库为https://github.com/tianocore/edk2.git 和https://github.com/tianocore/edk2-libc.git,可以使用如下命令去下载:

$ git clone --branch stable/202011 https://github.com/tianocore/edk2.git
$ git clone https://github.com/tianocore/edk2-libc.git

当然,取决于你所在地方的网速,下载速度会很慢。建议使用同样的方法,将github上的仓库同步到gitee上,或者直接在gitee上找到同样的仓库再下载。

本篇使用的分支为stable/202011,后续的实验结果均是基于此版本得出的。

3)更新子模块

修改edk2中的.gitmodules,更子模块。

如果能使用github直接下载,可以不用修改.gitmodules,直接运行后续的更新命令就可以了。我修改的内容如下:

[submodule "CryptoPkg/Library/OpensslLib/openssl"]
	path = CryptoPkg/Library/OpensslLib/openssl
	url = https://gitee.com/luobing4365/openssl.git
[submodule "SoftFloat"]
	path = ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
	url = https://gitee.com/luobing4365/berkeley-softfloat-3.git
[submodule "UnitTestFrameworkPkg/Library/CmockaLib/cmocka"]
	path = UnitTestFrameworkPkg/Library/CmockaLib/cmocka
	url = https://gitee.com/luobing4365/cmocka.git
[submodule "MdeModulePkg/Universal/RegularExpressionDxe/oniguruma"]
	path = MdeModulePkg/Universal/RegularExpressionDxe/oniguruma
	url = https://gitee.com/luobing4365/oniguruma.git
[submodule "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli"]
	path = MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
	url = https://gitee.com/luobing4365/brotli.git
[submodule "BaseTools/Source/C/BrotliCompress/brotli"]
	path = BaseTools/Source/C/BrotliCompress/brotli
	url = https://gitee.com/luobing4365/brotli.git
ignore = untracked

再次提醒,上述的子模块给出的地址,均是我将子模块在github上的仓库,导到gitee上的地址。可以参考我的方法,但是不要直接使用,这些都是我的私有地址,没法直接用。

具体的导入方法,可以参考UEFI开发探索57的内容。

接着使用如下命令,更新子模块:

$ git submodule update --init

4)编译工具

将ekd2-libc中的三个文件夹:AppPkg、StdLib和StdLibPrivateInternalFiles,全部复制到edk2目录下,方便后续的编译。(当然也可以不这么做,之前的博客中介绍过方法,请自行查阅)

打开Visual Studio的Native命令行(比如“VS2015 x86 Native Tools Command Prompt”),使用如下命令编译BaseTools以及其他的工具:

C:\edk202011\edk2> edksetup.bat Rebuild

编译完成后,BaseTools及其他工具会自动生成。

可以使用如下命令,测试开发环境是否搭建成功:

C:\edk202011\edk2> build -p AppPkg\AppPkg.dsc -a IA32

会发现提示错误。主要是因为AppPkg的第31行,有这么一句话(我使用的是最新的StdLib库-20210821):

!include MdePkg/MdeLibs.dsc.inc

edk2的源代码中,并没有找到这个文件。在语句前加符号“#”,将此句注释掉,再次编译AppPkg。可以看到编译成功,表示开发环境搭建好了。

2 搭建网络测试环境

本次搭建的网络测试环境,只针对EDK2的32位模拟环境。主要是因为Intel所提供的NetNt32Io文件,只支持32位的。虽然EDK2模拟环境(EmulatorPkg编译)支持32位和64位,测试64位的网络程序,还是在实际机器上进行吧。

搭建步骤如下:

1)安装Winpcap

Winpcap是一款用于网络抓包的专业软件,是一个免费、公共的网络访问系统。它能为win32应用程序提供访问网络底层的能力,在模拟器中,相当于网卡的驱动。下载地址为:

https://www.winpcap.org/default.htm。

此工具必须安装,通过模拟器发出的网络包,会被Winpcap抓到并转发。

2)编译SnpNt32Io

从github上将源码下载到本地:https://github.com/tianocore/edk2-NetNt32Io。

在C盘下建立文件夹NetNt32Io,将源代码复制进去。

然后下载Winpcap的开发包WpdPack,下载地址为:https://www.winpcap.org/devel.htm。解压WpdPack,复制到刚才建立的文件夹NetNt32Io中。建立好的目录如下:

图1 SnpNt32Io编译目录结构

打开Visual Studio的命令行(与编译UEFI代码的命令行相同),进入到源码目录,输入如下命令:

C:\NetNt32Io> nmake TARGET=RELEASE

NetNt32Io文件夹中会自动生成目录Release_IA32,目录中包含我们需要的SnpNt32Io.dll。

3)编译EDK2模拟器

按如下命令编译32位模拟器:

C:\edk202011\edk2> edksetup.bat
C:\edk202011\edk2> build -p EmulatorPkg\ EmulatorPkg.dsc -a IA32

所编译的出的模拟器,位于文件夹C:\edk202011\edk2\Build\EmulatorIA32\DEBUG_VS2015x86\IA32下。

4)配置模拟器网络环境

将之前编译好的SnpNt32Io.dll复制到模拟器所在目录,并在此目录下建立批处理文件loadnetwork.nsh,内容为:

load MnpDxe.efi ArpDxe.efi Ip4Dxe.efi VlanConfigDxe.efi Udp4Dxe.efi Dhcp4Dxe.efi Mtftp4Dxe.efi TcpDxe.efi

批处理文件中的UEFI驱动,都可以在模拟器目录下找到,编译模拟器的时候一起编译生成的。

双击模拟器目录下的执行文件WinHost.exe,启动模拟器,进入UEFI Shell环境。运行批处理文件,加载网络相关驱动:

Shell> fs0:
FS0:\> loadnetwork.nsh

我机器的IP地址为192.168.181.132,网关为192.168.181.2。将模拟器中的网络地址设置为192.168.181.135,命令如下:

FS0:\> ifconfig -s eth0 static 192.168.181.135 255.255.255.0 192.168.181.2

配置完成后,可以使用“ifconfig -l eth0”和ping命令查看是否配置成功。

FS0:\> ifconfig -l eth0
name       : eth0
Media State  : Media state unknown
policy       : static
mac addr    : 00:0C:29:D5:97:D7
ipv4 address  : 192.168.181.135
subnet mask  : 255.255.255.0
default gateway: 192.168.181.2

 Routes(2 entries):
   Entry[0]
Subnet  : 192.168.181.0
Netmask : 255.255.255.0
Gateway: 0.0.0.0
   Entry[1]
Subnet  : 0.0.0.0
Netmask : 0.0.0.0
Gateway: 192.168.181.2
DNS server   :

FS0:\> ping 192.168.1.42
ping 192.168.1.42 16data bytes.
16 bytes from 192.168.1.42 : icmp_seq=1 ttl=0 time0~26ms
…

我的UEFI开发用机器,是Vmware虚拟机,操作系统为Win10,UEFI的开发环境是在其上构建的。宿主机的操作系统也为Win10,宿主机上跑了一堆的虚拟机,用来进行各种不同需求的开发。

宿主机相当于局域网内的另外一台机器,其IP地址为192.168.1.42。

总之,到此为止,网络环境搭建完成了,下面进行网络程序测试。

3 网络程序测试

之前为了测试UEFI的网络,开发了Windows端的服务器程序和UEFI端的客户端程序,分别为EchoServerTCP4.exe和EchoTcp4.efi。

EchoServerTcp4.exe的程序之前就编译好了,只需要编译客户端的代码。

将UEFI开发探索博客的仓库中的RobinPkg,复制到现在搭建的UEFI开发环境中,编译EchoTcp4.efi:

C:\edk202011\edk2>build -p RobinPkg\RobinPkg.dsc -m RobinPkg\Applications\EchoTcp4\EchoTcp4.inf -a IA32

(近期我重新修改了EchoTcp4了,代码更新过。实际上,使用stdEchoTcp4项目也是一样的。)

把编译好的EchoTcp4.efi,复制到模拟器所在的目录。

在宿主机上运行服务器程序,EDK2模拟器上运行客户端程序,测试结果如下:

图2 测试网络通信

当然,也可以使用常用的网络调试助手来进行测试。测试结果如下:

图3 使用网络调试助手测试

平常我很少需要调试UEFI的网络程序,因此一直都用本篇方法搭建好的环境进行测试。

实验过程中,也发现几个问题:
1)防火墙会影响包的发送,最好把防火墙全部关掉。也许是Winpcap的抓包能力被影响了,我没有使用过Winpcap写过程序,了解原理的网友可以帮忙看下;

2)设置EDK2模拟器网址的时候,设置为dhcp的时候,有的时候成功,有的不成功,怀疑与路由器有关。具体原因未知,也许在深入模拟器原理后能解释这问题。

3)在运行EDK2模拟器的操作系统上,使用服务端软件和模拟器上的客户端软件通信,是不成功的。也就是说,服务端软件需要运行在同局域网内的其他机器上才行。比如我使用的宿主机跑服务端软件,虚拟机Win10跑EDK2模拟器,模拟器上跑客户端软件。宿主机和虚拟机相当于是在一个局域网内,所以运行正常。

这些问题供大家参考,具体原因我也不清楚,欢迎大家留言讨论。

为方便实验,我把本篇实验需要的Winpcap、WdpPack(Winpcap开发包)和NetNt32Io的源码放到了仓库里:

Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目文件位于:/ 97 Network-Emulator下

130 total views, 1 views today


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK