网卡驱动基础部分
每个网络接口都由一个net_device结构来描述,
该结构可使用如下内核函数动态分配:
1、struct net_device *alloc_netdev(int sizeof_priv, const char
*mask, void (*setup)(struct net_device *))
sizeof_priv 私有数据区大小;mask:设备名;setup 初始化函数
2、struct net_device *alloc_etherdev(int sizeof_priv)
结构net_device 的主要成员包括:
vchar name[IFNAMSIZ]
设备名,如:eth%d 如:eth0,eth1
vunsigned long state
设备状态
nsigned long base_addr
I/O 基地址
vunsigned int irq
中断号
int (*init)(struct net_device *dev) 初始化函数。该函数在register_netdev时被调用来完成对net_device 结构的初始化。
int (*open)(struct net_device *dev)打开接口。ifconfig 激活时,接口将被打开。
int (*stop)(struct net_device *dev)停止接口。该什么时候调用呢?
int (*hard_start_xmit) (struct sk_buff*skb, struct net_device *dev)数据发送函数。
设备注册
网络接口驱动的注册方式与字符驱动不同之处在于它没有主次设备号,并使用如下函数注册。
int register_netdev(struct net_device *dev )
Linux内核中的每个网络数据包都由一个套接字缓冲区结构struct sk_buff 描述,即一个sk_buff结构就是一个网络包,指 sk_buff的指针通常被称做skb。
该结构包含如下重要成员:
struct device *dev; //处理该包的设备
__u32 saddr; //IP源地址
__u32 daddr; //IP 目的地址
__u32 raddr; //IP路由器地址
sk_buff
unsigned char *head; //分配空间的开始
unsigned char *data; //有效数据的开始
unsigned char *tail; //有效数据的结束
unsigned char *end; //分配空间的结束
unsigned long len; //有效数据的长度
操作sk_buff的内核函数如下:
struct sk_buff *alloc_skb(unsigned int len,int priority)
分配一个sk_buff 结构,供协议栈代码使用
struct sk_buff *dev_alloc_skb(unsigned intlen)
分配一个sk_buff 结构,供驱动代码使用
Skb操作函数
unsigned char *skb_push(struct sk_buff*skb, int len) 后移动skb的tail指针,并返回tail移动之前的值。
unsigned char *skb_put(struct sk_buff *skb,int len)前移动skb的head指针,并返回head移动之后的值。
kfree_skb(struct sk_buff *skb)释放一个sk_buff 结构,供协议栈代码使用
dev_kfree_skb(structsk_buff *skb)释放一个sk_buff 结构,供驱动代码使用