[国嵌攻略][133][网卡驱动架构分析]

Linux网络子系统

1.系统调用接口:提供系统调用

2.协议无关接口:统一网络协议给系统调用接口使用

3.网络协议栈  :实现网络协议

4.设备无关接口:统一设备驱动程序给网络协议使用

5.设备驱动程序:实现网卡驱动

Linux驱动在内核中都有一个结构来描述,首先找到设备描述结构,然后找到设备如何注册和初始化。

网卡描述结构

在Linux内核中,每个网卡都由一个net_device结构来描述,其中一些重要成员:

char name[IFNAMSIZ]   设备名,如:eth%d

unsigned long base_addr   I/O基地址

const strcut net_device_ops *netdev_ops   网卡操作集合

网卡操作集合

类似于字符设备驱动中的file_operations结构,net_device_ops结构记录了网卡所支持的操作。

struct const struct net_device_ops dm9000_netdev_ops = {

    .ndo_open = dm9000_open,

    .ndo_stop = dm9000_stop,

    .ndo_start_xmit = dm9000_start_xmit,

    .ndo_do_ioctl = dm9000_ioctl,

    .ndo_validate_addr = eth_validate_addr,

    .ndo_set_mac_address = eth_mac_addr

};

网络数据包

Linux内核中每个网络数据包都由一个套接字缓冲区结构struct sk_buff描述,即一个sk_buff结构就是一个网络包,指向sk_buff的指针通常称为skb,例如:struct sk_buff *skb。

struct sk_buff结构内的成员有:head,data,tail,end。head和end是网络包的起始地址和结束地址,data和tail是网络包有效数据的起始位置和结束位置。data和tail的范围不会超过head和end的范围。

网卡驱动架构分析CS8900.c

分析网卡驱动程序时一般分析驱动的初始化,发送和接收。首先要找到模块的入口module_init,但是在早期的Linux驱动程序中模块的入口是init_module。网卡数据的发送函数在net_device_op操作集合中,网卡数据的接收在中断中完成。

网卡初始化

1.分配net_device,使用alloc_etherdev

2.初始化net_device结构

2.1.初始化中断号

2.2.初始化基地址

2.3.初始化MAC地址

2.4.初始化netdev_ops

3.初始化硬件

4.注册网卡驱动,使用register_netdev

网卡数据发送

1.通知上层协议暂停向网卡传送数据,使用netif_stop_queue

2.将skb中的数据写入网卡寄存器发送

3.释放skb空间,使用dev_kfree_sbk

43发送中断处理过程中,通知上层协议,可以再次向网卡传输数据,使用netif_wake_queue

网卡数据接收

1.读取接收状态

2.读取接收的数据长度

3.分配skb结构,使用dev_alloc_skb

4.从网卡寄存器中读出数据,存入skb

5.将收到的数据包skb交给协议栈,使用netif_rx

原文地址:https://www.cnblogs.com/d442130165/p/5266160.html