网络设备驱动
1、Linux 网络类设备不在是基于文件操作(没有对应的映射到文件系统中的设备节点),而是套接字socket来实现通讯
2、Linux 网络子系统的架构图
各层次接口功能说明:
系统调用接口层:为应用程序提供访问网络子系统的统一方法。
协议无关层:提供通用的方法来使用传输层协议。
协议栈的实现:实现具体的网络协议
设备无关层:协议与设备驱动之前通信的通用接口
设备驱动程序:
3、驱动程序数据结构
数据包描述结构:struct sk_buff
a) 所在头文件:<linux/sk_buff.h>
b) sk_buff为Linux网络层提供高效的缓冲区处理和流量控制机制,对驱动开发来说比较关心的是sk_buff结构体中的以下数据:
struct sk_buff
{
unsigned int len, /*数据包包含的数据量*/
....
sk_buff_data_t tail; /* 用于指向数据包载荷的结束*/
sk_buff_data_t end; /* 用于指向数据包的结束*/
unsigned char *head; /* 用于指向数据包的开始*/
unsigned char *data; /* 用于指向数据包载荷的开始*/
...
}
网卡描述结构:struct net_device
1、一个网卡结构表示一个具体设备
struct net_device
{
char name[IFNAMSIZ]; /*设备接口名,如eth0 */
...
unsigned long mem_end; /* shared mem end */
unsigned long mem_start; /* shared mem start */
unsigned long base_addr; /* device I/O address */
unsigned int irq; /* device IRQ number */
...
/* Management operations */
const struct net_device_ops *netdev_ops;/*网卡设备操作集*/
const struct ethtool_ops *ethtool_ops;
}
网卡操作描述结构:struct net_device_ops
和字符设备的原理差不多
网卡使用函数
结构分配:
1、alloc_netdev(....):回环网卡分配
2、alloc_ieee80211():WIFI无线网卡分配
3、ndev = alloc_etherdev(sizeof(struct xxx)):对1加工而已,适用于以太网卡
网卡设备注册:
ret = register_netdev(ndev);
网卡设备注销:
free_netdev(ndev);
4、Linux网络设备驱动体系架构分析
设备初始化:
1、申请网络设备:
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
2、初始化设备dev
a.中断号
b.I/O基地址
c.填充MAC地址(在捕获设备中进行)
d.关联操作函数集:dev->netdev_ops = &net_ops;(捕获设备中进行)
3、捕获设备:初始化硬件(或者在open函数中进行)
4、向内核注册网卡驱动:retval = register_netdev(dev);
网卡发送函数:.ndo_start_xmit = net_send_packet,
1、 通知上层协议停止发送数据:netif_stop_queue(dev);
2、 将skb的数据写入发送寄存器中
3、 释放skb空间:dev_kfree_skb (skb);
4、 在发送中断处理函数中(网卡有多种类型中断:接收数据包可产生 中断,发送数据包也可以产生中断)通知上层协议可以再次向网卡 传输数据netif_wake_queue(dev);-->唤醒发送队列
网卡接收(在中断中进行):net_rx(struct net_device *dev)
1、读取接收状态
2、读取接收数据长度
3、分配SKB结构:skb = dev_alloc_skb(length + 2); /*构造新数据包*/
4、从网卡寄存器中读取数据填入SKB结构
5、使用netif_rx(skb);将skb数据包发送给上层协议去处理