当前位置:编程学习 > C/C++ >>

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++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,