([一)建筑
要掌握的知识点:
1. Linux协议栈级别
2. Linux网络子系统架构
([二)协议栈
Linux的优势之一是其丰富而稳定的网络协议栈。它的范围从协议无关的层(例如通用套接字层接口或设备层)到各种特定的网络协议实现。
协议简介
网络的理论介绍通常采用OSI(开放系统互连)模型,但是Linux中对网络堆栈的介绍通常分为四层Internet模型。

网络接口层
网络接口层将数据链路层和物理层结合在一起,以提供用于访问物理设备的驱动程序。对应的网络协议主要是以太网协议
Internet层
网络层协议管理离散计算机之间的数据传输。例如,IP协议为用户和远程计算机提供了一种传输信息包的方法,以确保信息包可以正确到达目标计算机。重要的网络层协议包括ARP(地址解析协议),ICMP(Internet控制消息协议)和IP协议(Internet协议)等。
运输层
传输层的功能包括:格式化信息流并提供可靠的传输。传输层包括TCP(传输控制协议)和UDP(用户数据报协议),这是传输层中最重要的协议。
应用层
应用程序层位于协议栈的顶部。它的主要任务是为应用程序提供服务,例如使用FTP(文件传输协议)来传输文件。常见的应用程序层协议为:HTTP,FTP,Telnet等。对于Linux网络设置,应用程序层是非常关键的层。 Linux服务器的配置文件主要针对应用层中的协议。
([三) Linux网络子系统
Linux网络子系统的顶部是系统调用接口层。它为用户空间应用程序提供了一种访问内核网络子系统的方法。它下面是独立于协议的层,它提供了使用传输层协议的通用方法。然后是特定协议的实现,包括嵌入式协议TCP,UDP,当然还有Linux中的IP。然后是独立于设备的层,它为协议和设备驱动程序之间的通信提供了一个通用接口,设备驱动程序位于底部

系统调用界面
为应用程序提供一种访问内核网络子系统的方法:套接字系统调用。
协议独立接口
实现一组通用功能以通过套接字访问各种协议。 Linux中的套接字由struct sock描述。该结构包含特定套接字所需的所有状态信息,套接字使用的特定协议以及可以在套接字上执行的一些操作。
网络协议

网络协议层用于实现各种特定的网络协议,例如TCP,UDP等。
设备独立接口
与设备无关的接口将协议与各种网络设备驱动程序相连。该层为底层网络设备驱动程序提供了一组常用功能,以使它们可以在高层协议堆栈上运行。首先,设备驱动程序可以通过调用register_netdevice或unregister_netdevice在内核中注册或注销。调用者首先填写net_device结构,然后将该结构传递给注册。内核调用其init函数(如果定义了此类函数),然后执行一组健全性检查,并将新设备添加到设备列表(内核中的活动设备列表)。
要将数据从协议层发送到设备,您需要使用dev_queue_xmit函数。此函数将数据排队并将其交给基础设备驱动程序以接收最终的传输消息。通常使用netif_rx执行。当基础设备驱动程序收到一条消息(包含在已分配的sk_buff中)时,它将通过调用netif_rx将数据上载到与设备无关的层,然后该函数通过netif_rx_schedule将sk_buff放在上层协议队列中。供以后处理。
驱动程序
网络体系结构的最底层是负责管理物理网络设备的设备驱动程序层
([四)网卡驱动程序设计设备说明
每个网络接口均由net_device结构描述,该结构可以使用以下内核函数动态分配:
1、 struct net_device * alloc_netdev(int sizeof_priv,const char * mask,void(* setup)(struct net_device *))
sizeof_priv专用数据区域大小; mask:设备名称;设置初始化功能
2、 struct net_device * alloc_etherdev(int sizeof_priv)
net_device
net_device结构的主要成员包括:
int(* init)(结构net_device * dev)
初始化功能。在register_netdev期间调用此函数以完成net_device结构的初始化
与字符驱动程序一样,网络设备还必须声明可以操作它的功能。某些操作可以保留为NULL,而某些操作可以使用ether_setup来使用默认设置。网络接口的设备方法可以分为两类:基本方法和可选方法。基本方法包括使用该接口所必需的方法。以及可选方法实现了更高级的功能。
基本方法
int(* open)(结构net_device * dev)
打开界面。激活ifconfig后,将打开该界面。
int(* stop)(结构net_device * dev)
停止界面。我什么时候叫它?
int(* hard_start_xmit)(struct sk_buff * skb,struct net_device * dev)
数据发送功能
可选操作
int(* do_ioctl)(结构net_device * dev,结构ifreq * ifr,int cmd)
处理特定于接口的ioctl命令
int(* set_mac_address)(结构net_device * dev,void * addr)
更改Mac地址的功能需要硬件支持此功能
设备注册
网络接口驱动程序的注册方法与字符驱动程序的不同之处在于,它没有主设备号和次设备号,并且使用以下功能进行注册。
int register_netdev(struct net_device * dev)
sk_buff
Linux内核中的每个网络数据包都由套接字缓冲区结构struct sk_buff描述,即sk_buff结构是一个数据包,并且指向sk_buff的指针通常称为skb。
该结构包含以下重要成员:
Skb操作功能
用于操作sk_buff的内核函数如下
struct sk_buff * alloc_skb(unsigned int len,int priority)
分配一个sk_buff结构供协议栈代码使用
struct sk_buff * dev_alloc_skb(unsigned int len)
分配一个sk_buff结构以供驱动程序代码使用
无符号字符* skb_push(struct sk_buff * skb,int len)
移回skb的尾指针,并在尾移之前返回该值。常用功能:
unsigned char * skb_put(struct sk_buff * skb,int len)
向前移动skb的头指针,并在头移动后返回该值。常用功能:
kfree_skb(struct sk_buff * skb)
释放协议栈代码使用的sk_buff结构
dev_kfree_skb(struct sk_buff * skb)
发布sk_buff结构以供驱动程序代码使用
设备已打开
int net_open(结构net_device * dev)
{
/ *应用程序中断* /
request_irq(dev-> irq,&net_interrupt,SA_SHIRQ,“ dm9000”,dev);
/ *设置寄存器,启动设备* /
........................
/ *开始发送队列* /
netif_start_queue(dev);
}
数据发送
当核心需要发送数据包时,它将调用hard_start_transmit函数,该函数最终将调用net_device结构中的hard_start_xmit函数指针。
数据接收
网络接口驱动程序可以通过两种方式实现消息接收:
中断和查询,Linux驱动程序大多使用中断模式。
接收过程
1、分配Skb
skb = dev_alloc_skb(pkt-> datalen + 2)
2、从硬件读取数据到Skb
3、调用netif_rx将数据传送到协议栈
netif_rx(skb)
中断处理
网络接口通常支持三种类型的中断:新消息到达时中断,消息传输完成时中断以及错误发生时中断。中断处理程序可以通过查看网卡中的中断状态寄存器来区分中断类型。
([五) DM9000网卡驱动程序分析芯片介绍
DM9000是经常在开发板上使用的网络芯片。它是一个高度集成的低功耗高速网络控制器。它可以直接连接到CPU,并支持10 / 100M以太网连接。该芯片带有16K SRAM。 (3KB用于发送,13KB用于接收)
Dm9000在接收到上层发送的以太网帧后开始侦听网络线路。如果线路繁忙,它将等待直到线路空闲为止,否则它将立即发送数据帧。接收时,它将解码后将从以太网接收的数据包缓存在芯片中,从而删除帧头和地址验证。通过CRC检查后,它将通知CPU已接收到数据帧
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-372603-1.html
那还不感觉用鱼雷