UEFI实战(10) Network
开始编程之前,首先要配置好开发环境。分两种情况,一是使用Nt32模拟环境,二是使用真实的UEFI环境。
Nt32网络设置可以参考 UEFI Network Stack for EDK Getting Started Guide, 简略说明如下:
1。 下载并安装Winpcap
2. 下载 SnpNt32Io 并编译
c:\> cd c:\SnpNt32Io
c:\ SnpNt32Io> nmake TARGET=RELEASE
c:\ SnpNt32Io> copy /y SnpNt32Io.dll c:\edk2\build\Nt32Pkg\vs2008\IA32\
3. 启动Nt32模拟器
4。 加载网络协议
Shell > fsnt0:
fsnt0:\> load SnpNt32.efi Mnp.efi Arp.efi Ip4.efi Ip4Config.efi Udp4.efi Dhcp4.efi Mtftp4.efi Tcp4.efi
5 配置网卡
fsnt0:\> ifconfig –s eth0 Dhcp
fsnt0:\> ifconfig –s eth0 static 192.168.0.125 255.255.255.0 192.168.0.1
如果使用真实的UEFI环境,首先要加载网卡驱动, 然后加载网络协议Snp.efi Mnp.efi Arp.efi Ip4.efi Ip4Config.efi Udp4.efi Dhcp4.efi Mtftp4.efi Tcp4.efi,配置网卡.
网络协议栈
Snp(EFI_SIMPLE_NETWORK_PROTOCOL) 用于初始化和关闭网络接口,发送和接收数据包,
Mnp(EFI_MANAGED_NETWORK_PROTOCOL) 提供异步 网络包I/O操作
Arp(EFI_ARP_PROTOCOL)用于将IP地址转换为物理地址www.zzzyk.com
IP、TCP、UDP协议我们都耳熟能详了。
下面我们介绍一下TCP Protocol(EFI_TCP4_PROTOCOL)的用法。如果你曾经用Socket写过程序,那么会很容易理解EFI_TCP4_PROTOCOL的用法。 我们知道Socket 客户端需要这么几步:
1。 Create Socket
2。 connect
3。 Send/Recv
4。 Close
EFI_TCP4_PROTOCOL与之相似,客户端需要如下几步:
1。 Create EFI_TCP4_PROTOCOL对象
2。 Configure
3。 Connect
4。 Transmit(send)/Receive(Recv)
5。 Close
其实我们可以把Configure和Connect算成一步。
我们可以把EFI_TCP4_PROTOCOL封装成一个Socket类
#define SocketWait(e) \{
UINTN index;\
Status = gBS->WaitForEvent(1, &(e), &index); \
}
typedef EFI_STAUTS SOCKET_STATUS;
class Socket
{
public:
Socket(EFI_HANDLE ImageHandle);
~Socket();
SOCKET_STATUS Config(UINT32 Ip32, UINT16 Port);
SOCKET_STATUS Connect();
SOCKET_STATUS Connect(UINT32 Ip32, UINT16 Port){Config(Ip32, Port); reuturn Connect();};
SOCKET_STATUS Close();
SOCKET_STATUS Send(CHAR8* Data, UINTN Lenth);
SOCKET_STATUS Recv(CHAR8* Buffer, UINTN Lenth);
BOOL Ready(){return (m_pServiceBinding != NULL);}
private:
SOCKET Initialize();
EFI_HANDLE m_SocketHandle;
EFI_TCP4_PROTOCOL* m_pTcp4Protocol;
EFI_SERVICE_BINDING_PROTOCOL* m_pServiceBinding;
EFI_TCP4_CONFIG_DATA* m_pTcp4ConfigData;
EFI_TCP4_TRANSMIT_DATA* m_TransData;
EFI_TCP4_RECEIVE_DATA* m_RecvData;
EFI_TCP4_CONNECTION_TOKEN ConnectToken;
EFI_TCP4_CLOSE_TOKEN CloseToken;
EFI_TCP4_IO_TOKEN SendToken, RecvToken;
};下面一步步来看
1. 首先是产生一个EFI_TCP4_PROTOCOL对象。
EFI_TCP4_SERVICE_BINDING_PROTOCOL.CreateChild()用于产生一个Driver Handle, 此driver上挂载了EFI_TCP4_PROTOCOL, 用OpenProtocol或LocateProtocol可以获得此Handle上的EFI_TCP4_PROTOCOL对象。代码如下:
Socket::Socket(EFI_HANDLE ImageHandle)
{
EFI_STATUS Status;
memset((void*)this, 0, sizeof(Socket));
m_SocketHandle = NULL;
Status = gBS->LocateProtocol ( &gEfiTcp4ServiceBindingProtocolGuid,
NULL,
(VOID **)&m_pServiceBinding );
if(EFI_ERROR(Status))
return Status;
Status = m_pServiceBinding->CreateChild ( m_pServiceBinding,
&m_SocketHandle );
if(EFI_ERROR(Status))
return Status;
Status = gBS->OpenProtocol ( m_SocketHandle,
&gEfiTcp4ProtocolGuid,
(VOID **)&m_pTcp4Protocol,
ImageHandle,
m_SocketHandle,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL );
if(EFI_ERROR(Status))
return Status;
this -> Init();
}
2. 第二步, Configure,用于设置服务端IP和端口,本地端IP和端口,需要注意的是Configure完成之后,连接还没有建立
SOCKET_STATUS Socket::Config(UINT32 Ip32, UINT16 Port)
{
EFI_STATUS Status = EFI_NOT_FOUND;
if(m_pTcp4ConfigData == NULL) return Status;
m_pTcp4ConfigData->TypeOfService = 0;
m_pTcp4ConfigData->TimeToLive = 0;
*(UINT*)(m_pTcp4ConfigData->AccessPoint.RemoteAddress.Addr) = Ip32;
m_pTcp4ConfigData->AccessPoint.RemotePort = Port;
*(UINT32*)(m_pTcp4ConfigData->AccessPoint.SubnetMask.Addr) = (255 | 255 << 8 | 255 << 16 | 0 << 24) ;
m_pTcp4ConfigData->AccessPoint.UseDefaultAddress = TRUE;
/// 如果UseDefaultAddress 为FALSE, StationAddress 要设置
//*(UINT32*)(m_pTcp4ConfigData->AccessPoint.StationAddress.Addr) = LocalIp;
m_pTcp4ConfigData->AccessPoint.StationPort = 61558;
m_pTcp4ConfigData->AccessPoint.ActiveFlag = TRUE;
m_pTcp4ConfigData->ControlOption = NULL;
Status = m_pTcp4Protocol ->Configure(m_pTcp4Protocol, m_pTcp4ConfigData);
return Status;
}
EFI_TCP4_CONFIG_DATA* m_pTcp4ConfigData 定义如下
//
***************************************************************
// EFI_TCP4_CONFIG_DATA
//
***************************************************************
typedef struct {
// Receiving Filters
// I/O parameters
UINT8 Type
补充:软件开发 , C++ ,