net_device剖析

       网络设备接口层为了千变万化的设备定义了统一、抽象的数据结构net_device结构体来实现多种硬件在软件层次上的统一。net_device本身是一个巨型结构体,包含网络设备的属性描述和操作接口。

(1)全局信息

char name[IFNAMESIZ];

name是网络设备的名称。

int (*init)(struct net_device *dev);

init 为设备初始化函数指针,如果这个指针被设置了,则网络设备被注册时调用该函数完成对net_device结构体的初始化。但是,设备驱动程序可以不实现这个函数并将其赋值为NULL。

(2)硬件信息

unsigned long mem_end;
unsigned long mem_start;

mem_start和mem_end 分别定义了设备所使用的共享内存的起始和结束地址


unsigned long base_addr;
unsigned char irq;
unsigned char if_port;
unsigned char dma;

base_addr 为网络设备I/O 基地址。
irq为设备使用的中断号。
if_port指定多端口设备使用哪一个端口,该字段仅针对多端口设备。例如,如果设备同时支持IF_PORT_10BASE2(同轴电缆)和IF_PORT_10BASET(双绞线),则可使用该字段。
dma 指定分配给设备的DMA通道。

(3)接口信息


unsigned short hard_header_len;

hard_header_len 是网络设备的硬件头长度,在以太网设备的初始化函数中,该成员被赋为ETH_HLEN,即14。

</pre><pre name="code" class="cpp">unsigned short type;

type是接口的硬件类型。


unsigned mtu;

mtu指最大传输单元(MTU)。


unsigned char dev_addr[MAX_ADDR_LEN];
unsigned char broadcast[MAX_ADDR_LEN];

dev_addr[ ]、broadcast[ ]无符号字符数组,分别用于存放设备的硬件地址和广播地址。对于以太网而言,这两个地址的长度都为6 个字节。以太网设备的广播地址为6个0xFF,而MAC地址需由驱动程序从硬件上读出并填充到dev_addr[ ]中。


unsigned short flags;
flags 指网络接口标志,以IFF_(interface flags)开头,部分标志由内核来管理,其他的在接口初始化时被设置以说明设备接口的能力和特性。接口标志包括IFF_UP(当设备被激活并可以开始发送数据包时,内核设置该标志)、IFF_AUTOMEDIA(设备可在多种媒介间切换)、IFF_BROADCAST(允许广播)、IFF_DEBUG(调试模式,可用于控制printk调用的详细程度)、IFF_LOOPBACK(回环)、IFF_MULTICAST(允许组播)、IFF_NOARP(接口不能执行ARP)、IFF_POINTOPOINT(接口连接到点到点链路)等。

(4)设备操作函数

int (*open)(struct net_device *dev);
int (*stop)(struct net_device *dev);

open()函数的作用是打开网络接口设备,获得设备需要的I/O 地址、IRQ、DMA通道等。stop()函数的作用是停止网络接口设备,与open()函数的作用相反。

int (*hard_start_xmit) (struct sk_buff *skb,struct net_device *dev);

hard_start_xmit() 函数会启动数据包的发送,当系统调用驱动程序的hard_start_xmit()函数时,需要向其传入一个sk_buff 结构体指针,以使得驱动程序能获取从上层传递下来的数据包。

void (*tx_timeout)(struct net_device *dev);

当数据包的发送超时时,tx_timeout ()函数会被调用,该函数需采取重新启动数据包发送过程或重新启动硬件等策略来恢复网络设备到正常状态。

int (*hard_header) (struct sk_buff *skb,
struct net_device *dev,
unsigned short type,
void *daddr,
 *saddr,
unsigned len);

hard_header()函数完成硬件帧头填充,返回填充的字节数。传入该函数的参数包括sk_buff 指针、设备指针、协议类型、目的地址、源地址以及数据长度。对于以太网设备而言,将内核提供的eth_header()函数赋值给hard_header 指针即可。

struct net_device_stats* (*get_stats)(struct net_device *dev);

get_stats()函数用于获得网络设备的状态信息,它返回一个net_device_stats 结构体。net_device_stats结构体保存了网络设备详细的流量统计信息,如发送和接收到的数据包数、字节数等。

int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
int (*set_config)(struct net_device *dev, struct ifmap *map);
int (*set_mac_address)(struct net_device *dev, void *addr);

do_ioctl()函数用于进行设备特定的I/O 控制。
set_config()函数用于配置接口,可用于改变设备的I/O 地址和中断号。

set_mac_address()函数用于设置设备的MAC地址。

int (*poll)( struct net_device *dev,int quota);

对于NAPI(网络中断缓和)兼容的设备驱动,将以轮询方式操作接口,接收数据包。NAPI 是Linux 系统上采用的一种提高网络处理效率的技术,它的核心概念就是不采用中断的方式读取数据包,而是采用首先借助中断唤醒数据包接收的服务程序,然后以轮询方式获取数据包。net_device结构体的上述成员需要在设备初始化时被填充。


(5)辅助成员。

unsigned long trans_start;
unsigned long last_rx;

trans_start记录最后的数据包开始发送时的时间戳,last_rx记录最后一次接收到数据包时的时间戳,这两个时间戳记录的都是jiffies,驱动程序应维护这两个成员。

void *priv;

priv 为设备的私有信息指针,与filp->private_data 的地位相当。设备驱动程序中应该以netdev_priv()函数获得该指针。


spinlock_t xmit_lock;
int xmit_lock_owner;

xmit_lock是避免hard_start_xmit()函数被同时多次调用的自旋锁。xmit_lock_owner则指当前拥有xmit_lock自旋锁的CPU的编号。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值