LINUX CH2 直接网卡编程技术.ppt
第二篇第二篇 网络编程方法与技术网络编程方法与技术网络编程技术概述网络编程技术概述:直接网卡编程(可编程芯片)基于packetdriver的编程技术基于NDIS的网络编程VPACKET,PACKET32Libpcap/WinpcapBerkeleySockets编程技术WinsockJAVA网络编程n在本篇介绍的网络编程方法中,直接网卡编程技术、基于网卡驱动程序的网络编程技术、基于NDIS的网络编程、VPACKET、PACKET32、Libpcap、Winpcap等方法处理(接收和发送)的是链路层数据包,一般用于网络协议分析、网络计费、网络监视与控制、防火墙系统、入侵检测系统等较底层的应用环境;而Socket、Winsock、Java等方法处理的是网络层以上的数据包,如IP、TCP、UDP等,一般用于用户之间的通信。n对于高层的网络编程方法,如ASP、JSP、.NET等,这些方法学习起来比较简单,本书不做介绍。直接网卡编程技术简介直接网卡编程技术简介本章学习目的(1)了解网卡的基本工作原理;(2)为今后的产品开发做准备第第 2 章:章:直接网卡编程技术n在OSI模型中,物理层和数据链路层的主要功能一般由硬件-网络适配器(也叫网卡)来完成。n每个工作站都安装有一块或多块网卡,每个网卡都有自己的控制器,用以确定何时发送,何时从网络上接受数据,并负责执行802.3所规定的规程,如构成帧,计算帧检验序列、执行编码译码转换等。2.1 2.1 网卡的基本工作原理网卡的基本工作原理2.1.1 Ethernet网络适配器的工作原理2.1.1 Ethernet网络适配器的工作原理n网络适配器(网卡)一般由可编程数据链路控制器、曼彻斯特编码/译码器、收发器接口(TRANSCEIVER INTERFACE)、控制电路和存储器等几部分组成,如图1所示。其中可编程数据链路控制器由微处理器和网络管理部分等组成。n最初这些组成部分分别由不同的集成电路来实现,如National公司的DP8390+8391+8392,INTEL公司的82501,82586(控制器)。目前已将它们集成到一个芯片内,如莲花公司的UMC9008。n不同的网络芯片其编程方法稍有区别,但原理类似。图1 网络适配器的结构 1.LAN1.LAN管理部分和微处理器管理部分和微处理器nLAN的管理部分是网络适配器的核心,负责执行所有规程和数据处理。微处理器部分包括微处理器芯片、RAM芯片和ROM芯片。n当PC机有数据要发送时,便中断微处理器,并将数据传送并存储在微处理器部分的RAM芯片中,命令它发送数据。微处理器还将来自PC机的信号转换为LAN的帧格式,随后命令LAN管理部分将数据发送到网络上。微处理监视发送过程,以检查发送是否成功。n一旦PC机准备好从网络上接收帧,它便中断微处理器,并通知它进行帧的接收。微处理器通过命令LAN管理部分开始接收帧来响应。微处理器对帧的接收过程进行监视。一旦接收的帧由LAN管理部分处理结束,微处理器便中断PC,将接收到的数据传给PC机。2.曼彻斯特编码/译码器n在LAN中,常用的编码方式有NRZ(不归零码)、曼彻斯特、差分曼彻斯特等。nIEEE802.3规定数据的传输必须用曼彻斯特编码进行。当PC机希望将数据发送到网络上时,总是以DMA方式逐字节地将数据传给LAN管理部分,LAN管理部分串行传给“不归零曼彻斯特编码器”,在这里进行曼彻斯特编码。3.发送和发送控制部分 发送和发送控制部分负责帧的发送。4.接收和接收控制部分 接收和接收控制部分负责帧的接收2.1.2 2.1.2 可编程链路控制器可编程链路控制器1.DMA通道n网卡上的可编程控制器通过DMA来与PC机交换数据,网络适配器一共提供两个相互独立的DMA通道:LOCAL DMA和REMOTE DMA,如图2所示。Local DMA:本地缓冲区与FIFO之间的DMA通道 Remote DMA:本地缓冲区与计算机之间的DMA通道n其中,本地DMA通道负责本地缓冲区与FIFO之间的数据传输。当网络适配器发送帧时,由本地DMA负责将本地缓冲区中的帧数据以字节或字(通过编程指定)方式送往FIFO,然后发送到网络传输介质上。如果在发送过程中发生碰撞,本地DMA在主机CPU不介入的情况下自动重发,最大重发次数为15次。若超过15次,表示本次发送失败,此时必须由主机CUP重新介入,再次启动本地DMA。n当网络适配器接收帧时,本地DMA自动完成由FIFO到本地缓冲区的以字节方式的数据传输,将接收到的数据缓存在本地接收缓冲区中,等到整个数据帧接收完后再通知主机取数。ISAEISAPCIbase+10h块数据转送系统地址64KBbuffermemory16-BYTEFIFO16-BYTEFIFOLOCALDMAREMOTEDMAControllerSYSTEMI/OPORTLOCALMICROPROCESSORMAINCPUMAINMEMORYSYSTEMDMACONTROLLER本地总线系统总线网络适配器计算机图2网络适配器的DMA结构示意图网络数据握手信号FIFODATA1.DMA1.DMA通道通道n远程DMA负责在主机内存与本地缓冲区之间以字节(或字)的方式交换数据。n当主机有数据要发送时,它将已准备好的帧(不含同步序列和CRC校验和)通过远程DMA通道传给网络适配器,然后启动网络适配器发送;当网络适配器接收到完整的数据帧后,以中断方式,通知主机通过远程DMA将接收到的数据取走。1.DMA1.DMA通道通道n注:两个DMA通道都采用32位寻址方式和8位或16位的数据传输方式;NIC允许远程DMA和本地DMA同时交叉操作完成各自的任务。2.2.数据缓存数据缓存RAM n每个网络适配器上都配置有数据缓冲区RAM,长度从16KB到64KB不等。n站地址寄存器固化在网卡上的PROM中,PROM的长度为32字节,其中6个字节的站地址占据了PROM的最低6个地址。nPROM和缓存RAM在网卡上统一编址,PROM处于低地址部分,缓存RAM处于高地址部分。FIFOFIFOCONTENTSLOCATION01234567LowerByteCountUpperByteCount0LastByteCRC1CRC2CRC3CRC4接收FIFOFIFOFIFOCONTENTSLOCATION01234567发送FIFOByteN-4ByteN-3(CRC1)Byte N-2(CRC2)ByteN-1(CRC3)ByteN(CRC4)LowerByteCountUpperByteCount0 在网卡中,数据的发送和接收有相应的FIFO缓冲区,主要是对发送或接收数据进行字节计数和CRC校验。FIFO的结构如图3所示。图3网卡FIFO结构n本地DMA通道使用缓冲环结构来提供对接收数据的缓存。n该缓冲环由一系列固定长度的缓冲区组成,每一个缓冲区的长度为256字节,并将它称为一页。换句话说,将缓冲环划分为一系列的页,每页的容量为256字节,网络适配器将从网上接收到的数据帧存放在缓冲环中。n缓冲环使用时通过两个指针来指定其范围,其中指定页面开始位置的指针称为起始页(Page Start)寄存器,指定页面结束位置的指针称为终止页(Page Stop)寄存器,如图4所示。图4 网络适配器接收缓冲环结构示意图 Buffer#1Buffer#2Buffer#3Buffer#4。Buffer#nPStartPStop123nn-1接收缓冲区接收缓冲环收发缓冲区 除了页面起始指针和页面终止指针外,编程时还要用到另外三个指针:(1)当前指针(CURR):网络适配器存放接收数据的指针 (2)边界指针(BNRY):网络适配器存放接收数据的截止指针 (3)下一包指针(Next_pkt):主机从网络适配器取数的指针。初始化:发送缓冲区首地址(高字节)=40h BNRY=PSTART=46h CURR=Next_pkt=Pstart+1=47h Pstop=80h图5 NE2000网络适配器缓冲区的使用情况示意图 n图5指示的是NE2000中发送缓冲区和接收缓冲区及其指针的使用情况(总的缓冲区长度为16KB)。发送缓冲区发送缓冲区 接收缓冲区接收缓冲区空未取走的数据空发发缓缓首址首址40hPstart46h边边界界指指针针下下一一包包指指针针当当前前指指针针(初初始始值值等等于于47h)Pstop80h收发缓冲区n在图5中,发送缓冲区占用6个页面,地址范围为:4000h-4500h(6*256=1536字节)。n起始页面PSTART=46H,终止页面PSTOP=80H,即接收缓冲区的地址范围为:4600h-8000h。n同时规定:BNRY=CURR时表示接收缓冲环满,BNRY=CURR-1时表示接收缓冲环空。2.2 网卡寄存器2.2.1 NIC内部寄存器1.网卡寄存器的管理网络适配器上的控制器是一个可编程芯片,通过其上面的一组内部寄存器来控制。这些寄存器:(1)分读和写两种不同操作(2)分页管理分为4个页来管理,每页16个内部寄存器,只占用16个I/O地址(0F),4页中地址偏移为0的寄存器为命令寄存器。对于同一地址,到底选中的是哪一个寄存器,由命令寄存器中的PS0和PS1两个比特位来控制。2.网卡寄存器的分类 (1)地址寄存器 网络MAC地址 (2)配置寄存器(4个)3.I/O地址 PC机的读写操作分为存储器读写和I/O读写。4.硬中断号 一般PC机具有两个中断控制芯片(8259),总共有16个硬中断,可供网卡选用的有8个。2.2.2 寄存器的定义1.NIC DMA寄存器格式 NIC的本地DMA和远程DMA均有相应的寄存器,格式如图6所示图图6 NIC DMA寄存器格式寄存器格式 本地DMA通道本地本地DMA发送寄存器发送寄存器TPSR页面开始TBCR0,1发送字节计数器1570本地本地DMA接收寄存器接收寄存器1570PstartPstopCURRBURYCLD0,1页面开始页面终止当前页面边界指针接收字节计数器当前本地DMA地址远程远程DMA寄存器寄存器1570开始地址字节计数器当前远程DMA地址RSAR0,1RBCR0,1CRDA0,1远程DMA通道2.NIC内部寄存器内部寄存器 n网络适配器上的控制器是一个可编程芯片,通过其上面的一组内部寄存器来控制。nNIC中的内部寄存器分为4个页面,每页各有16个寄存器,每个寄存器由分为读操作和写操作两种,由命令寄存器CR中的PS0和PS1、控制器芯片上的管脚RA0RA3读写信号、片选信号等信号共同选择,如图7所示。图7 NIC内部寄存器映射 PS0,PS1命令寄存器CR地址译码/SWR/SRD/CSRA0RA3Page0writePage0readPage1writePage1readPage2writePage2readPage3writePage3readn命令寄存器中的PS0和PS1位用来确定访问那一页的寄存器,选择的对应关系为:n管脚RA0-RA3用来决定选择页内的那一个寄存器,共4位,最多能区分16个不同的寄存器。n选定寄存器后,到底是读操作还是写操作,由读写信号来决定,当读信号有效时表示读操作,写信号有效时为写操作。n当然,上述操作都必须在片选信号有效的情况下才有效。PS0 PS1选中的页面 00 01 10 1 1 Page 0 Page 1 Page 2 Page 3nNIC上的寄存器分为配置寄存器和控制寄存器。其中,(1)配置寄存器用于配置网络适配器的工作方式,其中常用的配置寄存器如表2-2(教材P76)所示。(2)控制寄存器用于通过软件来控制网络适配器的工作,各个页面寄存器的定义如表2-2(教材P76)所示。2.2.3 寄存器描述1.配置寄存器2.控制寄存器类比:串口编程n串行口8250/16550/16650/16750地址寄存器3F8收/发缓冲器,除数寄存器低位3F9中断允许寄存器,除数寄存器高位3FA中断识别寄存器,FIFO控制寄存器3FB线路控制寄存器3FCMODEM控制寄存器3FD线路状态寄存器3FEMODEM状态寄存器3FFFIFO状态寄存器初始化发送接收状态检测2.3 NE2000(9008)编程要点编程要点 n网卡的数据端口地址为I/O基地址+10h,软件复位端口地址为基地址+1fh,假定I/O基地址为300h,则数据端口地址为310h,软件复位口为31fh。2.3.1 2.3.1 初始化初始化 软复位。读写软件复位端口,即从端口(BIOA+1fh)出读数据,延迟一定时间后在将读出的数据写回该端口。选择0页,软件复位:向命令寄存器写入21H,CR21H。设置数据结构寄存器:DCR49h。设置接收配置寄存器:RCR04h(接收正确的本站及广播包)。设置发送配置寄存器:TCR00h,设定网卡是工作在外部发送模式(00H)还是内部自检方式。(02H)初始化初始化 清除所有的网卡中断:中断状态寄存器ISR49h。设置中断屏蔽寄存器:IMR7fh。初始化接收缓冲环:PSTART46h PSTOP80h(4600h8000h)BURY=PSTART46h 清除远程DMA字节计数器:(BIOA+0Ah)00h。(BIOA+0Bh)00h 初始化初始化 读取网卡地址:将存在网卡PROM中的6个字节(存放地址在00000005单元)的网卡物理地址,通过远程DMA取出并存入网卡内部寄存器中的物理地址寄存器(1页的前面6个字节),同时存入网卡物理地址缓冲区,以供以后数据打包用。初始化初始化 设置接收缓冲环当前指针(即接收缓冲环写指针,1页的BIOA+07h处)为远程DMA起始页面寄存器的值加1,即CURR47h。设置主机取数指针,即下一包指针:Next_pkt=47h。设置发送缓冲区首地址:CR47h (4000h45ffh)BIOA+04h40h 设置PC硬中断。2.3.2 2.3.2 发送发送 n发送前,客户程序首先根据Ethernet帧格式将要发送的数据组帧(不用计算CRC校验和,它在发送时由硬件自动完成,也不包含同步序列),并将组装好的数据帧存放到缓冲区中,然后通过远程DMA,将内存中的数据帧传送给网络适配器,最后启动网卡发送。具体的数据发送操作如下:发送发送 第一步:将待发送的数据帧传送到网卡发送缓冲区。设置远程DMA起始地址为网卡发送缓冲区首地址。设置远程DMA操作的字节数(等于数据帧的长度)。启动远程DMA写操作:CR12h。通过PC机的端口输出指令(OUTPORT或OUTPROTB)依次将数据帧送往网络适配器(送到网卡的数据端口)。第二步:启动网卡发送。(1)将远程DMA字节计数器清零。(2)设置发送字节计数寄存器TBCR0,1。用户生成的数据 帧 的 长 度=6(目 的 地 址)+6(远 源 地 址)+2(TYPE)+数据长度。(3)启动网卡发送:CR26h。2.3.3 2.3.3 中断接收处理中断接收处理 NE2000(9008)网卡接收到完整的数据帧后,通过中断来通知用户将接收到的数据取走。接收中断处理操作如下:第一步:从网卡接收缓冲区取数。设置远程DMA起始指针:RSAR00;RSAR1Next_pkt 设置远程DMA操作的字节数:RBCR00;RBCR16,即按最大长度来设置(以太网 帧最大长度为1500字节)。启动远程DMA读:CR0Ah。中断接收处理中断接收处理 利用读端口指令(INPOUT后INPORTB)从网卡的数据端口(BIOA+10H)依次读入数据。在读入的数据中,最前面的4个字节不是数据帧的内容,而是接收控制数据,它们的定义为:第一个字节为接受状态,其定义与接收状态寄存器的定义相同;第二个字节为下一个包的页面地址指针;第三、第四字节表示接收数据的字节数。Receive statusReceive statusNext Packet PointerNext Packet PointerReceive Byte Count 0Receive Byte Count 0Receive Byte Count1Receive Byte Count1Byte1Byte1Byte2Byte2 .n808x_type processors808x_type processorsn68000-type processors Next Packet PointerReceive StatusReceive Byte Count 1Receive Byte Count 0Byte 2Byte 1Next Packet PointerReceive StatusReceive Byte Count 0Receive Byte Count 1Byte 1Byte 2NE2000(9008)网卡接收缓冲区的前几个字节的内容网卡接收缓冲区的前几个字节的内容中断接收处理中断接收处理 将读入数据的第二字节-下一个包的页面指针送入Next_pkt指针,其它数据根据用户需求处理。第二步:修改接收指针。修改边界指针:BNRY=Next_pkt-1 清除远程DMA字节计数寄存器:RBCR00;RBCR10。NE2000(9008)网卡缓冲区结构如图9(下一页)所示中断接收处理中断接收处理发送缓冲区接收缓冲区空未取走的数据空发缓首址40hPstart46h边界指针下一包指针当前指针(初始值等于47h)Pstop80h1#包2#包3#包4#包接收状态下一包地址指针数据长度有效数据主机从这里取数图9NE2000(9008)网卡缓冲区结构中断接收处理中断接收处理n需要注意的是,在接收过程中,每次接收都要判断各个指针是否合法,不合法时表示网卡工作出现了混乱,不能接收混乱的数据帧。2.3.4 2.3.4 接收缓冲环溢出处理方法接收缓冲环溢出处理方法 1)发送停止模式(STOP MODE)命令(CR=21H)。注意:UM9008可能不会立即进入停止模式,如果此时它正在处理报文,将等到报文处理完后才进入停止模式。UM9008通过设置中断状态寄存器中的RST位来表示它已进入停止模式。2)清除远程字节计数寄存器(RBCR0,RBCR1)。UM9008要求在设置RST位之前远程计数寄存器必须被清除。3)查看中断状态寄存器的RST位,如果置1,则表示ENC处在停止模式。接收缓冲环溢出处理方法接收缓冲环溢出处理方法4)通过向发送配置寄存器写入02或04,进入LOOPBACK模式。当UM9008工作在活跃的网络中时,这一步是必不可少的。5)发送开始模式命令(CR=22H),此时由于UM9008处在LOOPBACK模式,故本地接收DMA还处在不活跃状态。6)从接收缓冲环中丢掉至少一个包,以便接纳新进入的数据包。7)通过设置TCR来使UM9008退出LOOPBACK状态,回到正常的工作状态。2.3.5 中断处理1.中断初始化2.中断处理n直接网卡编程实例(见WORD文档)n说明:该程序是用汇编语言编写的、针对UM9008网卡芯片的网络通信程序,主要功能包括网卡初始化、数据帧的发送和接收、接收缓冲环处理等。该程序已经在实际产品中使用。2.4 网卡编程实例Thanks!