第九章 Linux网络设备驱动程序.ppt_第1页
第九章 Linux网络设备驱动程序.ppt_第2页
第九章 Linux网络设备驱动程序.ppt_第3页
第九章 Linux网络设备驱动程序.ppt_第4页
第九章 Linux网络设备驱动程序.ppt_第5页
免费预览已结束,剩余26页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

,Linux网络设备驱动程序,第9章,本章目标,了解Linux网络驱动程序的数据交换过程掌握移植和编写具体网卡驱动程序的方法,本章结构,Linux网络设备驱动程序,Linux网络设备驱动的结构,网络设备的注册、注销和初始化,网络设备的打开和释放,数据包发送,数据包接收,网络连接状态,参数设置和统计数据,Linux网络设备简介,网络设备,又叫网络接口是Linux第三类标准设备网络设备和块设备类似,在内核的特定数据结构中注册自己当发生网络数据交换时,网络设备驱动程序注册的方法将被内核调用网络设备不会在/dev下存在一个设备入口,它使用保留的内部设备名,网络设备的特点,网络设备异步的接收外来的数据包,有别于其他设备网络设备主动的“请求”将硬件获得的数据包压入内核,而其他设备例如块设备被“请求”向内核发送缓冲区网络设备同时要执行大量的管理任务设置地址修改传输参数维护流量和流量控制错误统计和报告,网络设备的特点,网络子系统是完全与协议无关的,网络驱动程序与内核其余部分之间的每次交互处理的都是一个网络数据包,9.1Linux网络设备驱动的结构,9.1.1网络协议接口层,最主要的功能是给上层协议提供了透明的数据包发送和接收接口。上层ARP或IP协议需要发送数据包时,调用网络协议接口层的dev_queue_xmit()函数上层对数据包的接收也通过向netif_rx()函数:,dev_queue_xmit(structsk_buff*skb);,intnetif_rx(structsk_buff*skb);,9.1.1网络协议接口层,套接字缓冲区(sk_buff)结构套接字缓冲区(sk_buff)结构是Linux内核网络子系统的核心内容,在中被定义sk_buff结构中的重要字段:structnet_device*rx_dev;structnet_device*dev;union/*.*/h;union/*.*/nh;union/*.*/mac;unsignedchar*head;unsignedchar*data;unsignedchar*tail;unsignedchar*end;unsignedlonglen;unsignedcharip_summed;unsignedcharpkt_type,分别为接收和发送缓冲区的设备,指向数据包中各个层的数据包头。h指向传输层包头,nh指向网络层包头,mac指向链路层包头,用来寻址数据包中的数据指针。head指向已分配空间开头,data指向有效的octet开头,tail指向有效的octet结尾,而end指向tail可以到达的最大地址,PACKET_HOSTPACKET_BROADCASTPACKET_MULTICASTPACKET_OTHERHOST,9.1.1网络协议接口层,structsk_buff*alloc_skb(unsignedintlen,intpriority);structsk_buff*dev_alloc_skb(unsignedintlen);,voidkfree_skb(structsk_buff*skb);voiddev_kfree_skb(structsk_buff*skb);,unsignedchar*skb_put(structsk_buff*skb,intlen);unsignedchar*_skb_put(structsk_buff*skb,intlen);,在缓冲区末尾添加数据,前一个函数会进行检查,释放套接字缓冲区,分配套接字缓冲区,9.1.1网络协议接口层,unsignedchar*skb_push(structsk_buff*skb,intlen);unsignedchar*_skb_push(structsk_buff*skb,intlen);,缓冲区头部添加数据,intskb_tailroom(structsk_buff*skb);,voidskb_reserve(structsk_buff*skb,intlen);,unsignedchar*skb_pull(structsk_buff*skb,intlen);,intskb_headroom(structsk_buff*skb);,返回缓冲区后部可用空间总量,返回缓冲区前面部分可用空间总量,在可填充缓冲区之前保留包头空间,从数据包头拿出数据,通常用来剥离数据包头,9.1.2网络设备接口层,net_device结构该结构是网络设备驱动的核心,它包含了许多成员。可以参考文件,阅读它的完整定义。net_device结构可分为全局成员硬件相关成员接口相关成员设备方法成员公用成员,9.1.2网络设备接口层,net_device结构的主要成员全局信息charnameIFNAMESIZint(*init)(structnet_device*dev)硬件信息unsignedlongrmem_end;unsignedlongrmem_start;unsignedlongmem_end;unsignedlongmem_start;unsignedlongbase_addr;unsignedcharirq;unsignedcharif_port;unsignedchardma;,如果被设置了,在register_netdev奖调用他初始化net_device结构,现代驱动一般在注册接口中完成初始化。,这些字段描述了设备共享内存的起止地址,描述设备的I/O基地址,描述设备中断号,描述多端口设备的活动端口,描述设备的DMA通道,9.1.2网络设备接口层,接口信息,int(*open)(structnet_device*dev);,int(*stop)(structnet_device*dev);,int(*hard_start_xmit)(structsk_buff*skb,structnet_device*dev);,int(*hard_header)(structsk_buff*skb,structnet_device*dev,unsignedshorttype,void*daddr,void*saddr,unsignedlen);,打开接口。当ifconfig激活网络设备时,接口被打开。通常我们在open方法里面完成资源的分配,包括I/O映射、中断注册、DMA注册等。同时激活硬件,并增加使用计数,停止接口。在这个方法里面,我们完成与open方法相反的,注销操作,该方法初始化数据包的传输。是网络设备驱动中非常重要的一个方法。我们将完整的数据包放入一个套接字缓冲区sk_buff结构里,根据先前检索到的源和目的硬件地址建立硬件头,9.1.2网络设备接口层,int(*rebuild_header)(structsk_buff*skb);,void(*tx_timeout)(structnet_device*dev);,structnet_device_stats*(*get_stats)(structnet_device*dev);,int(*set_config)(structnet_device*dev,structifmap*map);,int(*do_ioctl)(structnet_device*dev,structifreq*ifr,intcmd);,void(*set_multicast_list)(structnet_device*dev);,用来在传输数据包之前重建硬件头,数据包发送在超时时间内失败,这时该方法被调用。这个方法应该解决失败的问题并重新开始发送数据包,当应用程序需要获得接口的统计信息时,这个方法被调用,改变接口的配置。比如改变I/O端口和中断号等,现在的驱动程序通常无需该方法,实现设备自定义的ioctl命令,当设备的组播列表改变或设备标志改变时,该方法被调用,9.1.2网络设备接口层,int(*set_mac_address)(structnet_device*dev,void*addr);,int(*change_mtu)(structnet_device*dev,intnew_mtu);,int(*header_cache)(structneighbour*neigh,structhh_cache*hh);,int(*hard_header_parse)(structsk_buff*skb,unsignedchar*haddr);,int(*header_cache_update)(structhh_cache*hh,structnet_device*dev,unsignedchar*haddr);,如果接口支持MAC地址改变,则可以实现该函数,当接口的MTU改变时,该方法将被调用,负责做出相应的特定处理,根据ARP查询的结果填充hh_cache结构,在发生变化时,该方法更新hh_cache结构中的目的地址,从skb中包含的数据包中获得源地址,并将其复制到位于haddr的缓冲区中,9.2.1网络设备的注册、注销,注册与注销函数创建net_device释放net_device,intregister_netdev(structnet_device*dev);voidunregister_netdev(structnet_device*dev);,structnet_device*alloc_netdev(intsizeof_priv,constchar*name,void(*setup)(structnet_device*);structnet_device*alloc_etherdev(intsizeof_priv);,voidfree_netdev(structnet_device*dev);,9.2.1网络设备的注册、注销,1intxxx_init_module(void)234/*分配net_device结构体并对其成员赋值*/5xxx_dev=alloc_netdev(sizeof(structxxx_priv),“sn%d”,xxx_init);6if(xxx_dev=NULL)7/*分配net_device失败*/89/*注册net_device结构体*/10if(result=register_netdev(xxx_dev)11121314voidxxx_cleanup(void)151617/*注销net_device结构体*/18unregister_netdev(xxx_dev);19/*释放net_device结构体*/20free_netdev(xxx_dev);21,9.3网络设备的打开和释放,网络设备的打开函数完成如下工作:使能设备使用的硬件资源,申请I/O区域、中断和DMA通道等。调用Linux内核提供的netif_start_queue()函数,激活设备发送队列。网络设备的关闭函数需要完成如下工作:调用Linux内核提供的netif_stop_queue()函数,停止设备传输包。释放设备所使用的I/O区域、中断和DMA资源。netif_start_queue()和netif_stop_queue()两个函数的原型,voidnetif_start_queue(structnet_device*dev);voidnetif_stop_queue(structnet_device*dev);,9.3网络设备的打开和释放,intxxx_open(structnet_device*dev)/*申请端口、IRQ等,类似于fops-open*/ret=request_irq(dev-irq,/*canttransmitanymore*/,9.4数据包发送,网络设备驱动完成数据包发送的流程如下:网络设备驱动程序从上层协议传递过来的sk_buff参数获得数据包的有效数据和长度,将有效数据放入临时缓冲区。对于以太网,如果有效数据的长度小于以太网冲突检测所要求数据帧的最小长度ETH_ZLEN,则给临时缓冲区的末尾填充0。设置硬件的寄存器,驱使网络设备进行数据发送操作。,9.4数据包发送,1intxxx_tx(structsk_buff*skb,structnet_device*dev)23intlen;4char*data,shortktETH_ZLEN;5/*获得有效数据指针和长度*/6data=skb-data;7len=skb-len;8if(lendata,skb-len);13len=ETH_ZLEN;14data=shortpkt;1517dev-trans_start=jiffies;/*记录发送时间戳*/19/*设置硬件寄存器让硬件把数据包发送出去*20 xxx_hw_tx(data,len,dev);2122,9.4数据包发送,传输超时处理当数据传输超时时,意味着当前的发送操作失败,此时,数据包发送超时处理函数xxx_tx_timeout将被调用。这个函数需要调用Linux内核提供的netif_wake_queue()函数重新启动设备发送队列。如下所示:,1voidxxx_tx_timeout(structnet_device*dev)234netif_wake_queue(dev);/*重新启动设备发送队列*/5,9.5数据包接收,网络设备接收数据的主要方法是由中断引发设备的中断处理函数,中断处理函数判断中断类型,如果为接收中断,则读取接收到的数据,分配sk_buffer数据结构和数据缓冲区将接收到的数据复制到数据缓冲区,并调用netif_rx()函数将sk_buffer传递给上层协议。,9.5数据包接收,staticvoidxxx_interrupt(intirq,void*dev_id,structpt_regs*regs)switch(status/*其他类型的中断*/,staticvoidxxx_rx(structxxx_device*dev)length=get_rev_len();/*分配新的套接字缓冲区*/skb=dev_alloc_skb(length+2);skb=reserve(skb,2);/*对齐*/skb-dev=dev;/*读取硬件上接收到的数据*/insw(ioaddr+RX_FRAME_PORT,skb_put(skb,length),length1);if(length/*记录接收时间戳*/.,9.6网络连接状态,网络适配器硬件电路可以检测出链路上是否有载波,载波

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论