IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 网卡-驱动-DMA API-TCP/IP -> 正文阅读

[网络协议]网卡-驱动-DMA API-TCP/IP

网卡的工作原理

网卡工作原理
https://www.cnblogs.com/menghuanbiao/p/5212244.html

分析网卡的工作原理其实是分析网卡的驱动程序

网络是独立的一个模块。为了屏蔽网络环境中物理网络设备的多样性,Linux对所有的设备进行抽象并定义了一个统一的概念,称之为接口。所有对网络硬件的访问都是通过接口进行的,接口提供了一个对所有类型的硬件一致化的操作集合来处理基本数据发送和接收。一个网络接口被看作是一个发送和接收数据包的实体。对于每个网络接口,都用一个net_device的数据结构来表示。net_device中有很多提供系统访问和协议层调用的设备方法,包括提供设备初始化和往系统注册用的init函数,打开和关闭网络设备的open和stop函数,处理数据包发送的函数hard_start_xmit,以及中断处理函数。

所有被发送和接收的包都用数据结构sk_buff表示。要发送数据时,网络系统将分局系统路由表选择相应的网络接口进行数据传输;当接收数据包时,通过驱动程序登记的中断服务程序进行数据的接口处理。

网卡初始化

网络设备初始化主要工作时检测设备的存在、初始化描述设备的net_device结构及在系统中登记该设备。

初始化过程首先检测网络物理设备是否存在,这是通过检测物理设备的硬件特征来完成;然后对设备进行资源配置,这些完成之后就要构造设备的net_device数据结构,用检测到值对net_device中的变量初始化;最后Linux内核中注册该设备并申请内存空间

网卡的打开与关闭

为了使用网络设备,需要打开网卡,打开和关闭的一个接口是由shell命令ifconfig调用的,而ifconfig则要调用一个通用的设备打开函数dev_open(net/core/dev.c),相应的还有一个dev_close函数,这两个函数提供独立于设备的操作接口的打开和关闭功能。

一般打开函数执行的操作包括注册中断函数,分配并初始化网卡所需要的接收与发送缓冲区,启动硬件检查网络连接线状态等。

从网卡到内存

数据包的发送和接收是实现Linux网络驱动程序中两个最关键的过程。

中断与轮询

在轮询方式中,系统每隔一定的时间间隔就去检查一次物理设备,若设备有数据到达,就调用读取数据的程序。Linux中通过定时器实现,但是此法有一个明显的缺点:不管设备是否有数据,系统总是要固定的消耗CPU资源去查看设备,并且可能对一些紧急数据处理予以延迟。从资源的利用率以及工作的效率上看不是最优。

中断方式利用硬件体系结构的中断机制实现设备和系统的应答对话,即当物理设备需要CPU处理数据时,就向CPU发送一个终端信号,系统则在收到信号后调用相应的中断服务程序响应对设备中断的处理。**因此,基本在所有的网络设备驱动程序中都是用中断方式的。**网卡发送/接收数据,都必须以中断的方式告诉系统,系统处理中断后做出相应操作。

每一个网卡上都有一块FIFO存储器,对于NIC(Network Interface Controller),FIFO存储器是用来通过系统总线传送数据到系统存储器之前,缓存从LAN上接收到的数据。对与快速以太网还有一个直接内存存取(DMA:Directly Memory Access)控制器,用于提供对系统存储器的可靠访问。

驱动为网卡分配一个环形缓冲区,在一段连续的物理内存中实现。

  1. 数据接收
    (1) 接收的数据包,先暂存于片内FIFO接收队列;
    (2) 当接收器达到早期接收上限时就移至环形缓冲区
    (3) 待整个数据包全部从片上存储移至 环形缓冲区 后,将接收状态寄存器和包长度写入接收的数据包头部,并更新CBA(Current Buffer Address)寄存器的值;网卡将数据包通过DMA的方式写入到指定的内存地址,该地址由网卡驱动分配并初始化。
    (4) CMD(Command)寄存器中的BufferEmpty位和ISR(中断状态寄存器)寄存器的ROK位置1,并发出ROK的中断;
    (5) ISR中断调用完成后,清除ISR(ROK)并更新CAPR(Current Address of Packet Read,指向接收缓存的已读取包的地址),完成本次接收。
    以上是硬中断,网卡的数据传输部分完成,然后交由Linux软中断进行协议处理等。

请添加图片描述
2. 数据发送
(1) 将待传送的数据写入主存中一段连续的缓存空间,由OS配合驱动程序完成;
(2) 找到一个可用的描述符,并写入内容,包括该数据包的开始物理地址和传输状态字(包的大小、可传送下限、OWN位);
(3) OWN位有效,将数据从缓存移至片内FIFO队列;
(4) 当FIFO队列中的数据达到早期传送下限,NIC的传送单元就会启动,将数据顺序输出至线路;
(5) 当整个数据包都已经传至FIFO,OWN位置1;
(6) 当整个数据包都已经传至线路上, TOK寄存器置1;
(7) 当TOK(IMR)和TOK(ISR)都置为1,就发出TOK中断;
(8) TOK中断调用完成以后,清除TSD状态字,完成本次传送。

网卡上存在一定大小的FIFO存储器,DMA缓冲区是由系统/驱动程序分配的一段连续的物理内存。

Linux网络 - 数据包的接收过程
https://segmentfault.com/a/1190000008836467
网卡到内存(硬中断+DMA),软中断会触发内核网络模块中的软中断处理函数,一顿操作后将数据包交给协议栈处理,最终通过socket唤醒应用程序。

DMA与缓冲区

驱动程序调用dma_map函数分配DMA缓冲区

地址转换

在这里插入图片描述
在PCI设备枚举(初始化)过程中,内核了解了所有的IO device及其对应的MMIO地址空间(MMIO是物理地址空间的子集),也了解了是PCI主桥设备将这些PCI device和系统连接在一起。

PCI设备会有BAR(base address register),表示自己在PCI总线上的地址范围,CPU并不能通过总线地址A(位于BAR范围内)直接访问总线上的PCI设备,PCI host bridge会在MMIO(即物理地址)和总线地址之间进行mapping。
因此,对于CPU,它实际上是可以通过B地址(位于MMIO地址空间)访问PCI设备(反正PCI host bridge会进行翻译)。地址B的信息保存在struct resource变量中,并可以通过/proc/iomem开放给用户空间。

对于驱动程序,它往往是通过ioremap()把物理地址B映射成虚拟地址C,这时候,驱动程序就可以通过ioread32?来访问PCI总线上的地址A了。

如果PCI设备支持DMA,那么在驱动中可以通过kmalloc或者其他类似接口分配一个DMA buffer,并且返回了虚拟地址X,MMU将X地址映射成了物理地址Y,从而定位了DMA buffer在系统内存中的位置。因此,驱动可以通过访问地址X来操作DMA buffer,但是PCI 设备并不能通过X地址来访问DMA buffer,因为MMU对设备不可见,而且系统内存所在的系统总线和PCI总线属于不同的地址空间。

在一些简单的系统中(没有IOMMU),设备可以通过DMA直接访问物理地址Y,但是在大多数的系统中,使用IOMMU硬件block将DMA可访问的总线地址翻译成物理地址,也就是把上图中的地址Z翻译成Y。

驱动程序在调用dma_map_single这样的接口函数的时候会传递一个虚拟地址X,在这个函数中会设定IOMMU的页表,将地址X映射到Z,并且将返回z这个总线地址。驱动可以把Z这个总线地址设定到设备上的DMA相关的寄存器中。这样,当设备发起对地址Z开始的DMA操作的时候,IOMMU可以进行地址映射,并将DMA操作定位到Y地址开始的DMA buffer。

缓冲区的使用方式

分为 一致性DMA映射 与 流式DMA映射

一致性DMA映射

Consistent / coherent DMA mapping:持续使用该DMA buffer(不是一次性的),因此Consistent DMA总是在初始化的时候进行map,在shutdown的时候unmap。

网卡驱动和网卡DMA控制器往往是通过一些内存中的描述符(形成环或者链)进行交互,这些保存描述符的memory一般采用Consistent DMA mapping。

流式DMA映射

streaming DMA mapping:流式DMA映射是一次性的,一般是需要进行DMA传输的时候才进行mapping,一旦DMA传输完成,就立刻ummap(除非使用dma_sync_*的接口,下面会描述)。并且硬件可以为顺序化访问进行优化。
一般使用streaming DMA mapping的场景包括:
(1)网卡进行数据传输使用的DMA buffer
(2)文件系统中的各种数据buffer

应用程序调用驱动程序分配缓冲区

DMA控制器硬件结构与DMA通道使用的地址

所谓DMA可以使用任意的内存地址是因为:应用层通过malloc 获得的DMA缓冲区内存,无法知道他的物理地址是多少,而且可能不连续。
(但是DMA内存在物理上要连续。)
在这里插入图片描述

想知道的问题:这个DMA缓冲区地址区间在哪?是如何划分的?
https://blog.csdn.net/junwua/article/details/80942295

数据传输可以以两种方式触发:一种软件请求数据,另一种由硬件异步传输。

  1. 软件请求数据
    调用的步骤可以概括如下(以read为例):
    (1)在进程调用 read 时,驱动程序分配一个 DMA 缓冲区,随后指示硬件传送它的数据。进程进入睡眠。
    (2)硬件将数据写入 DMA 缓冲区并在完成时产生一个中断。
    (3)中断处理程序获得输入数据,应答中断,最后唤醒进程,该进程现在可以读取数据了。

  2. 由硬件异步传输
    在 DMA 被异步使用时发生的。以数据采集设备为例:
    (1)硬件发出中断来通知新的数据已经到达。
    (2)中断处理程序分配一个DMA缓冲区
    (3)外围设备将数据写入缓冲区,然后在完成时发出另一个中断。
    (4)处理程序利用DMA分发新的数据,唤醒任何相关进程。

网卡传输也是如此,网卡有一个循环缓冲区(通常叫做 DMA 环形缓冲区)建立在与处理器共享的内存中。每一个输入数据包被放置在环形缓冲区中下一个可用缓冲区,并且发出中断。然后驱动程序将网络数据包传给内核的其它部分处理,并在环形缓冲区中放置一个新的 DMA 缓冲区。

驱动分配缓冲区的方式

驱动可以通过系统接口(例如__get_free_page*())或者类似kmalloc() or kmem_cache_alloc()这样的通用内存分配的接口来分配DMA buffer,这些接口函数返回的虚拟地址可以直接用于DMA mapping接口API,并通过DMA操作在外设和dma buffer中交换数据。
不推荐使用kmap()和vmalloc()分配DMA buffer。

DMA shadow buffer两篇论文

重新理解:固定的是虚拟地址 最左边这一列
在这里插入图片描述
在IOMMU里固定好了映射
做的事情主要是VA(DMA缓冲区)的管理与分配了

扩展到VM

IOMMU里存的是全部GPA-HPA的映射
请添加图片描述
对于GuestOS:
在GuestOS内固定一块虚拟内存,专用做DMA缓冲区,防止DMA缓冲区乱窜。在IOMMU中固定好映射关系。

存疑:
1、guestos里面是否有IOMMU机制?
没有的话怎么绕过hypervisor访问物理iommu?
2、VM初始化的时候与IOMMU初始化的时候设置IOMMU页表
3、编程模型GVA-GPA,GuestOS内网络I/O的时候内存虚拟地址VA(DMA缓冲区)如何分配的问题

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-30 12:32:49  更:2021-08-30 12:34:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:35:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码