您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > Linux网络设备驱动程序
火龙果整理uml.org.cnLinux网络设备驱动程序第9章火龙果整理uml.org.cn本章目标了解Linux网络驱动程序的数据交换过程掌握移植和编写具体网卡驱动程序的方法火龙果整理uml.org.cn本章结构Linux网络设备驱动程序Linux网络设备驱动的结构网络设备的注册、注销和初始化网络设备的打开和释放数据包发送数据包接收网络连接状态参数设置和统计数据火龙果整理uml.org.cnLinux网络设备简介网络设备,又叫网络接口是Linux第三类标准设备网络设备和块设备类似,在内核的特定数据结构中注册自己当发生网络数据交换时,网络设备驱动程序注册的方法将被内核调用网络设备不会在/dev下存在一个设备入口,它使用保留的内部设备名火龙果整理uml.org.cn网络设备的特点网络设备异步的接收外来的数据包,有别于其他设备网络设备主动的“请求”将硬件获得的数据包压入内核,而其他设备例如块设备被“请求”向内核发送缓冲区网络设备同时要执行大量的管理任务设置地址修改传输参数维护流量和流量控制错误统计和报告火龙果整理uml.org.cn网络设备的特点网络子系统是完全与协议无关的,网络驱动程序与内核其余部分之间的每次交互处理的都是一个网络数据包火龙果整理uml.org.cn9.1Linux网络设备驱动的结构火龙果整理uml.org.cn89.1.1网络协议接口层最主要的功能是给上层协议提供了透明的数据包发送和接收接口。上层ARP或IP协议需要发送数据包时,调用网络协议接口层的dev_queue_xmit()函数上层对数据包的接收也通过向netif_rx()函数:dev_queue_xmit(structsk_buff*skb);intnetif_rx(structsk_buff*skb);火龙果整理uml.org.cn9.1.1网络协议接口层套接字缓冲区(sk_buff)结构套接字缓冲区(sk_buff)结构是Linux内核网络子系统的核心内容,在linux/skbuff.h中被定义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火龙果整理uml.org.cn109.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);在缓冲区末尾添加数据,前一个函数会进行检查释放套接字缓冲区分配套接字缓冲区火龙果整理uml.org.cn119.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);返回缓冲区后部可用空间总量返回缓冲区前面部分可用空间总量在可填充缓冲区之前保留包头空间从数据包头拿出数据,通常用来剥离数据包头火龙果整理uml.org.cn129.1.2网络设备接口层net_device结构该结构是网络设备驱动的核心,它包含了许多成员。可以参考include/linux/netdevice.h文件,阅读它的完整定义。net_device结构可分为全局成员硬件相关成员接口相关成员设备方法成员公用成员火龙果整理uml.org.cn9.1.2网络设备接口层net_device结构的主要成员全局信息charname[IFNAMESIZ]int(*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通道火龙果整理uml.org.cn9.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结构里根据先前检索到的源和目的硬件地址建立硬件头火龙果整理uml.org.cn9.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命令当设备的组播列表改变或设备标志改变时,该方法被调用火龙果整理uml.org.cn9.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的缓冲区中火龙果整理uml.org.cn9.2.1网络设备的注册、注销注册与注销函数创建net_device释放net_deviceintregister_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);火龙果整理uml.org.cn189.2.1网络设备的注册、注销1intxxx_init_module(void)2{3…4/*分配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)))11…12}1314voidxxx_cleanup(void)15{16…17/*注销net_device结构体*/18unregister_netdev(xxx_dev);19/*释放net_device结构体*/20free_netdev(xxx_dev);21}火龙果整理uml.org.cn199.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);
本文标题:Linux网络设备驱动程序
链接地址:https://www.777doc.com/doc-1307012 .html