当前位置:文档之家› 第九章 Linux网络设备驱动程序

第九章 Linux网络设备驱动程序

用来在传输数据包之前重建硬件头 int (*rebuild_header)(struct sk_buff *skb); 数据包发送在超时时间内失败,这时 该方法被调用。这个方法应该解决失 败的问题并重新开始发送数据包 void (*tx_timeout)(struct net_device *dev); 当应用程序需要获得接口的统计信息时,这个方法被调用 struct net_device_stats *(*get_stats)(struct net_device *dev); 改变接口的配置。比如改变I/O端口和中断号 等,现在的驱动程序通常无需该方法 int (*set_config)(struct net_device *dev, struct ifmap *map); 实现设备自定义的ioctl命令 int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); 当设备的组播列表改变或设备 标志改变时,该方法被调用 void (*set_multicast_list)(struct net_device *dev);
netif_start_queue()和netif_stop_queue()两个函数的原型
int skb_tailroom(struct sk_buff *skb);
返回缓冲区后部可用空间总量
int skb_headroom(struct sk_buff *skb);
返回缓冲区前面部分可用空间总量
void skb_reserve(struct sk_buff *skb, int len);
网络设备,又叫网络接口是Linux第三类标准设备 网络设备和块设备类似,在内核的特定数据结构中注册自 己 当发生网络数据交换时,网络设备驱动程序注册的方法将 被内核调用 网络设备不会在/dev下存在一个设备入口,它使用保留的 内部设备名
网络设备的特点
网络设备异步的接收外来的数据包,有别于其他设备
网络设备主动的“请求”将硬件获得的数据包压入内 核,而其他设备例如块设备被“请求”向内核发送缓 冲区 网络设备同时要执行大量的管理任务
int (*stop)(struct net_device *dev);
停止接口。在这个方法里面,我们完 成与open方法相反的,注销操作
该方法初始化数据包的传输。是网络设备驱动中非常重要的一个方法。我们将 完整的数据包放入一个套接字缓冲区sk_buff结构里 int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev);
描述设备的I/O基地址 描述设备中断号 描述多端口设备的活动端口 描述设备的DMA通道
9.1.2 网络设备接口层
接口信息
int (*open)(struct net_device *dev);
打开接口。当ifconfig激活网络设备 时,接口被打开。通常我们在open方 法里面完成资源的分配,包括I/O映射、 中断注册、DMA注册等。同时激活硬 件,并增加使用计数
9.2.1 网络设备的注册、注销 注册与注销函数
int register_netdev(struct net_device *dev); void unregister_netdev(struct net_device *dev);
创建net_device
struct net_device *alloc_netdev(int sizeof_priv, const char *name, void (*setup)(struct net_device*)); struct net_device *alloc_etherdev(int sizeof_priv);
9.1.2 网络设备接口层
如果接口支持MAC地址改 变,则可以实现该函数 int (*set_mac_address)(struct net_device *dev, void *addr); 当接口的MTU改变时, 该方法将被调用,负责 做出相应的特定处理 int (*change_mtu)(struct net_device *dev, int new_mtu); 根据ARP查询的结果填充hh_cache结构 int (*header_cache) (struct neighbour *neigh, struct hh_cache *hh); 在发生变化时,该方法更新 hh_cache结构中的目的地址 int (*header_cache_update) (struct hh_cache *hh, struct net_device *dev, unsigned char *haddr); 从skb中包含的数据包中获得源地址,并 将其复制到位于haddr的缓冲区中 int (*hard_header_parse) (struct sk_buff *skb, unsigned char *haddr);
全局成员 硬件相关成员 接口相关成员 设备方法成员 公用成员
9.1.2 网络设备接口层
net_device 结构的主要成员
全局信息
char name[IFNAMESIZ] int (*init)(struct net_device *dev)
如果被设置了,在register_netdev奖 调用他初始化net_device结构,现代 驱动一般在注册接口中完成初始化。
释放net_device
void free_netdev(struct net_device *dev);
9.2.1 网络设备的注册、注销
1 int xxx_init_module(void) 2{ 3 … 4 /*分配net_device结构体并对其成员赋值*/ 5 xxx_dev = alloc_netdev(sizeof(struct xxx_priv),“sn%d”, xxx_init); 6 if(xxx_dev == NULL) 7 …/*分配net_device失败*/ 8 9 /*注册net_device结构体*/ 10 if((result = register_netdev(xxx_dev))) 11 … 12 } 13 14 void xxx_cleanup(void) 15 { 16 … 17 /*注销net_device结构体*/ 18 unregister_netdev(xxx_dev); 19 /*释放net_device结构体*/ 20 free_netdev(xxx_dev); 21 }
unsigned char *head; unsigned char *data; unsigned char *tail; unsigned char *end; unsigned long len; unsigned char ip_summed; unsigned char pkt_type
指向数据包中各个层的数据包头。h指向传 输层包头,nh指向网络层包头,mac指向 链路层包头 用来寻址数据包中的数据指针。head指向 已分配空间开头,data指向有效的octet开 头,tail指向有效的octet结尾,而end指向 tail可以到达的最大地址 PACKET_HOST PACKET_BROADCAST PACKET_MULTICAST PACKET_OTHERHOST
dev_queue_xmit(struct sk_buff *skb);
上层对数据包的接收也通过向netif_rx()函数:
int netif_rx(struct sk_buff *skb);
9.1.1 网络协议接口层
套接字缓冲区(sk_buff)结构
套接字缓冲区(sk_buff)结构是Linux内核网络子系统的核心内 容,在<linux/skbuff.h>中被定义 sk_buff结构中的重要字段: struct net_device *rx_dev; 分别为接收和发送缓冲区的设备 struct net_device *dev; union { /* ... */ } h; union { /* . . . */ } nh; union { /*... */} mac;
9.3 网络设备的打开和释放
网络设备的打开函数完成如下工作:
使能设备使用的硬件资源,申请I/O区域、中断和DMA通道等。 调用Linux内核提供的netif_start_queue()函数,激活设备发送队列。
网络设备的关闭函数需要完成如下工作:
调用Linux内核提供的netif_stop_queue()函数,停止设备传输包。 释放设备所使用的I/O区域、中断和DMA资源。
9.1.1 网络协议接口层
struct sk_buff *alloc_skb(unsigned int len, int priority); struct sk_buff *dev_alloc_skb(unsigned int len); 分配套接字缓冲区
void kfree_skb(struct sk_buff *skb); void dev_kfree_skb(struct sk_buff *skb); 释放套接字缓冲区
设置地址 修改传输参数 维护流量和流量控制 错误统计和报告
网络设备的特点
网络子系统是完全与协议无关的,
网络驱动程序与内核其余部分之间的每次交互处理的 都是一个网络数据包
9.1 Linux网络设备驱动的结构
9.1.1 网络协议接口层
最主要的功能是给上层协议提供了透明的数据包发送 和接收接口。 上层ARP或IP协议需要发送数据包时,调用网络协议 接口层的dev_queue_xmit()函数
第9章
Linux网络设备驱动程序
本章目标
了解Linux网络驱动程序的数据交换过程 掌握移植和编写具体网卡驱动程序的方法
本章结构
Linux网络设备驱动的结构 网络设备的注册、注销和初始化 网络设备的打开和释放 Linux网络设备驱动程序 数据包发送 数据包接收 网络连接状态
相关主题