b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

Linux网络子系统的协议无关层到驱动层的体系结构

电脑杂谈  发布时间:2021-05-02 22:02:54  来源:网络整理

一、协议栈级别比较

网络设备器驱动程序

二、 Linux网络子系统

Linux网络子系统的顶部是系统调用接口层。它为用户空间提供的应用程序提供了一种访问内核网络子系统的方法(套接字)。它下面是独立于协议的层,它提供了使用传输层协议的通用方法。然后是特定协议的实现,包括内核协议TCP,UDP,当然还有Linux中的IP。然后是独立于设备的层,它为协议和设备驱动程序之间的通信提供了一个通用接口,而设备驱动程序位于底部。

网络设备器驱动程序

与设备无关的接口将协议与各种网络驱动程序连接。该层为较低级别的网络设备驱动程序提供了一组常规功能,以使它们可以在较高级别的协议堆栈上运行。需要从协议层到设备生成数据,需要调用dev_queue_xmit函数,此函数将数据排队,然后移交给基础驱动程序的hard_start_xmit方法以最终完成传输。接收通常使用netif_rx执行。当底层设备程序收到消息(发生中断)时,它将调用netif_rx将数据上传到与设备无关的层。

三、从设备无关层到驱动程序层的体系结构

下图显示了从设备无关层到驱动程序层的体系结构

网络设备器驱动程序

1),网络协议接口层为网络层协议提供了统一的数据包接收和发送接口。无论高层协议是ARP还是IP,都通过dev_queue_xmit()函数发送数据,并通过netif_rx()函数接收数据。该层的存在使上层协议独立于特定设备。

2)。网络设备接口层为协议接口层提供了一个统一的结构net_device,该结构描述了特定网络设备的属性和操作。该结构是设备驱动程序功能层中每个功能的容器。实际上,网络设备接口层从宏观角度规划了特定操作硬件的设备驱动程序功能层的结构。

3),设备驱动程序功能层的每个功能都是网络设备接口层net_device数据结构的特定成员,是一个驱动网络设备硬件完成相应动作的程序,他通过以下方式开始发送操作函数hard_start_xmit()并传递给网络设备触发器上的中断触发了接受操作。

4)。网络设备和媒体层是完成数据包(包括网络适配器和特定传输媒体)的发送和接收的物理实体。网络适​​配器由驱动程序功能层中的功能物理驱动。对于Linux系统,网络设备和媒体都可以是虚拟的。

1、网络协议接口层:

这里主要用于发送和接收数据包,使用的功能原型是:

dev_queue_xmit(struct sk_buff *skb);int netif_rx(struct sk_buff *skb);  

这里使用了一个skb_buff结构,该结构在include / linux / skbuff.h中定义,它的意思是“套接字缓冲区”,用于在Linux网络子系统的各个层之间传输数据。这是一个双链表。在旧内核中,将有一个指向sk_buff_head的列表字段,它是链接列表的头,但是在我研究的linux 2. 6. 3 0. 4内核中不再存在,如下所示:

网络设备器驱动程序

sk_buff中的重要数据成员

结构设备* dev;正在处理包裹的设备

__ u32 sadd; r // IP中继地址

__ u32 daddr; // IP目标地址

__ u32 raddr; // IP路由器地址

unsigned char * head; //开始分配空间

unsigned char * data; //有效数据的开头

无符号字符* tail; //有效数据的结尾

unsigned char * end; //已分配空间的结尾

unsigned long len; //有效数据的长度

sk_buff操作

a-分配:分配sk_buff结构供协议栈代码使用

struct sk_buff *alloc_skb(unsigned int len, int priority);
struct sk_buff *dev_alloc_skb(unsigned int len);  

分配一个缓冲区。 alloc_skb函数分配一个缓冲区,并将skb-> data和skb-> tail初始化为skb-> head。参数len是数据缓冲区空间的大小,通常与L1_CACHE_BYTES字节对齐(对于ARM为3 2),参数优先级是内存分配的优先级。dev_alloc_skb()函数使用GFP_ATOMIC优先级来分配skb。

b-发布:

void kfree_skb(struct sk_buff *skb);
void dev_kfree_skb(struct sk_buff *skb); 

在Linux内核内部使用kfree_skb()函数,而在网络设备驱动程序中最好使用dev_kfree_skb()。

sk_buff中更重要的成员是指向数据包中数据的指针,如下图所示:

网络设备器驱动程序

用于寻址数据包中数据的指针,头指向已分配空间的开头,数据指向有效八位位组的开头,尾指向有效八位位组的末尾,终点指向尾部可以达到的最大地址。如果不这样做,则分配一个固定大小的缓冲区,如果该缓冲区不足,则必须申请更大的缓冲区,然后将其复制并增加它,这会降低性能。

3)更改

unsigned char *skb_put(struct sk_buff *skb, int len);将taill指针向后移动len长度,并返回tail移动之前的值。用于向skb有效数据区域末尾添加数据。
unsigned char *skb_push(struct sk_buff *skb, int len);将data指针向前移动len长度。并返回移动之后的值。用于向skb有效数据区域前端添加数据(包头)。
unsigned char *skb_pull(struct sk_buff *skb, int len);
void skb_reserve(struct sk_buff ×skb, int len); 

下图对应于这四个功能。阅读完此图后,您应该清楚这四个功能的作用。

网络设备器驱动程序

2、网络设备接口层:

网络设备接口层的主要功能是为不断变化的网络设备定义统一的抽象数据结构net_device结构,以在软件级别实现各种硬件的统一,从而保持不变并做出响应进行更改。

每个网络设备由struct net_device描述。可以使用以下内核函数动态分配该结构。

网络设备器驱动程序_程序多开器最新_程序多开器

struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void(*setup)(struct net_device *))

sizeof_priv是私有数据区的大小; mask是设备名称,setup是初始化函数,在注册设备时调用该函数。即net_deivce的init成员。

struct net_device *alloc_etherdev(intsizeof_priv)

此功能与上面的功能之间的区别在于内核知道它将设备视为以太网设备并进行一些相关的初始化。

net_device结构可以分为五个部分:全局成员,与硬件相关的成员,与接口相关的成员,设备方法成员和公共成员

a-主要全球成员

char name[INFAMSIZ]    设备名,如:eh%d
unsigned long state  设备状态
unsigned long base_addr  I/O基地址
unsigned int irq   中断号

b-主要设备方法

//首先看打开和关闭网络设备的函数:
int (*open)(struct net_device *dev);
//打开接口。ifconfig激活时,接口将被打开
int (*stop)(struct net_device *dev);  
//停止接口,ifconfig eth% down时调用
//要注意的是ifconfig是interface config的缩写,通常我们在用户空间输入:
//ifconfig eth0 up  会调用这里的open函数。
//在用户空间输入:
//ifconfig eth0 down  会调用这里的stop函数。
//在使用ifconfig向接口赋予地址时,要执行两个任务。首先,它通过ioctl(SIOCSIFADDR)(Socket I/O Control Set Interface Address)赋予地址,然后通过ioctl(SIOCSIFFLAGS)(Socket I/O Control Set Interface Flags)设置dev->flag中的IFF_UP标志以打开接口。这个调用会使得设备的open方法得到调用。类似的,在接口关闭时,ifconfig使用ioctl(SIOCSIFFLAGS)来清理IFF_UP标志,然后调用stop函数。
int  (*init)(struct  net_device *dev)
//初始化函数,该函数在register_netdev时被调用来完成对net_device结构的初始化
int (*hard_start_xmit)(struct sk_buf*skb,struct net_device *dev)
//数据发送函数
int (*hard_header)(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); 
//该方法根据先前检索到的源和目的硬件地址建立硬件头
int (*rebuild_header)(struct sk_buff *skb);
//以太网的mac地址是固定的,为了高效,第一个包去询问mac地址,得到对应的mac地址后就会作为cache把mac地址保存起来。以后每次发包不用询问了,直接把包的地址拷贝出来。
void (*tx_timeout)(struct net_device *dev);  
//如果数据包发送在超时时间内失败,这时该方法被调用,这个方法应该解决失败的问题,并重新开始发送数据。
struct net_device_stats *(*get_stats)(struct net_device *dev);  
//当应用程序需要获得接口的统计信息时,这个方法被调用。
int (*set_config)(struct net_device *dev, struct ifmap *map);  
//改变接口的配置,比如改变I/O端口和中断号等,现在的驱动程序通常无需该方法。
int (*do_ioctl)(struct net_device *dev, struct ifmap *map);  
//用来实现自定义的ioctl命令,如果不需要可以为NULL。
void (*set_multicast_list)(struct net_device *dev);  
//当设备的组播列表改变或设备标志改变时,该方法被调用。
int (*set_mac_address)(struct net_device *dev, void *addr);  
//如果接口支持mac地址改变,则可以实现该函数。

3、设备驱动程序接口层:

net_device结构的成员(属性和函数指针)需要由设备驱动程序功能层的特定值和函数给出。对于xxx的特定设置,工程师应编写设备驱动程序功能层函数,例如xxx_open(),xxx_stop(),xxx_tx(),xxx_hard_header(),xxx_get_stats(),xxx_tx_timeout()等。

4、网络设备和媒体层:

网络设备和媒体层直接对应于实际的硬件设备。

网络设备注册

网络设备注册方法和字符驱动程序之间的区别在于,它没有主设备号和次设备号,并使用以下功能进行注册

int register_netdev(struct net_deivce*dev)

注销网络设备

void unregister_netdev(struct net_device*dev)

四、驱动程序的实现

1)初始化(初始化)

设备检测工作是在init方法中进行的,通常称为probe方法的功能

初始化的主要任务是检测设备,配置和初始化硬件,最后将这些资源应用到系统中。另外,为了填充设备的dev结构,我们调用内核提供的ether_setup方法来设置一些以太网默认设置。

程序多开器最新_网络设备器驱动程序_程序多开器

2)打开(打开)

在网络设备驱动程序中激活网络设备(即,设备状态从向下更改为向上)时将调用open方法

实际上,许多初始化工作可以在这里完成。例如,资源应用程序和硬件激活。如果dev-> open返回非零值,则硬件状态仍为关闭,

寄存器中断,DMA等;设置寄存器,启动设备;开始发送队列

通常,注册中断是在init中完成的,但是在网卡驱动程序中,大多数注册中断都是在开放状态册的,因为必须频繁关闭并重新启动网卡

3)关闭(停止)

stop方法的作用与打开的工作相反

可以释放一些资源以减轻系统负担

当设备状态从上到下变化时调用Stop

4)发送(hard_start_xmit)

当系统调用驱动程序的hard_start_xmit时,发送的数据将放置在sk_buff结构中。通用驱动程序发送到硬件。还有一些特殊的设备,例如环回,可以将数据组合成接收数据并将其发送到系统,或者虚拟设备直接丢弃数据。

如果传输成功,则hard_start_xmit方法将释放sk_buff。如果设备暂时无法处理(例如硬件繁忙),则返回1。

5)接收

驱动程序没有接受方法。接收到数据后,驱动程序将调用netif_rx函数将skb移交给与设备无关的层。

通常,设备在接收到数据后将产生一个中断。在中断处理程序中,驱动程序申请一块sk_buff(skb),以将数据位置从硬件读取到应用程序编号的缓冲区。

接下来,在sk_buff中填写一些信息。

可以通过接收数据或完成传输来产生中断。中断处理程序需要判断中断类型。如果是数据接收中断,它将开始接收数据。如果是传输完成中断,则将在传输完成后进行处理。一些操作,例如重新启动发送队列。

接收过程:

1、分配skb = dev_alloc_skb(pkt-> datalen + 2)

2、从硬件读取数据到skb

3、调用netif_rx将数据传送到协议栈

中断处理

网络接口通常支持三种类型的中断:新消息到达时中断,消息传输完成时中断以及错误发生时中断。中断处理程序可以通过查看网卡的中断状态寄存器来区分中断类型。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-372585-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...