Linux 操作系统原理 — PCIe 总线标准

news/2024/5/3 16:46:06/文章来源:https://blog.csdn.net/Jmilk/article/details/130030012

目录

文章目录

  • 目录
  • 总线系统
  • PCIe 总线
    • PCIe 总线的传输速率
    • PCIe 总线的架构
  • PCIe 外设
    • PCIe 设备的枚举过程
    • PCIe 设备的编址方式
      • BDF(Bus-Device-Function)编号
      • BAR(Base Address Register)地址
  • Linux 上的 PCIe 设备
    • 查看 PCIe 设备的 BDF
    • 查看 PCIe 设备的 Vendor ID 和 Device ID
    • 查看 PCIe 设备的详细信息

总线系统

总线系统(Bus System),用于完成主机(CPU + Main Memory)和 I/O 外设(网卡、磁盘)等内部组件之间的通信。

在这里插入图片描述

从功能实现上,可以分为 3 种总线类型:

  1. 数据总线:用于在 CPU 与 Main Memory 或 I/O 设备之间传输数据。
  2. 地址总线:用于在 CPU 与 Main Memory 或 I/O 设备之间传输地址信息。
  3. 控制总线:用于在 CPU 与 Main Memory 或 I/O 设备之间传输控制信号。

从系统模块的角度,总线系统主要由 2 大部分组成:

  1. CPU 总线,又称为 FSB(Front Side Bus,前端总线)
  2. PCI/PCIe 总线

在这里插入图片描述

PCIe 总线

PCIe(Peripheral Component Interconnect Express,快速外设组件互连标准)是一种高速总线技术,用于统一连接 NIC、Disk、GPU 等多种类型的 I/O 外设。

PCIe 总线的传输速率

在这里插入图片描述

PCIe 使用 GT/s(Giga transmission per Second)作为传输速率的计量单位,区别于网络带宽的计量单位 Gbps(Giga bits per second)。因为 PCIe 协议具有 “行代码比“ 开销,根据不同的编码方案,会占用一定量的原始信道带宽。

所以,PCIe 带宽吞吐量的计算公式为:带宽 = 传输速率 x 行代码比。例如:PCIe 2.0 采用的编码方案是 8b/10b,含义是 10bits 数据里面,有 2bits 是额外的开销,实际上只传递了 8bits 的实际数据。所以,PCIe 2.0 每一条 Lane 的带宽为 5GT/s x 8b / 10b = 500MB/s,那么 PCIe 2.8 x 8 Lane 设备的总带宽就是 500MB/s x 8 = 4GB/s。

通常我们只需要关注实际的吞吐量数据,只是需要区分两者的差别。另外,PCIe 协议支持向前兼容的特性,如果设备支持 PCIe 4.0,但计算机主板支持只支持 PCIe 3.0,那么系统就只能以 3.0 的传输速率运行。

PCIe 总线的架构

相较于更早前的 PCI Bus 采用的共享并行互联架构,所有 I/O 设备共用一个总线带宽,导致整体性能不高。PCIe Bus 则采用了串行互联架构,以点对点的形式进行数据传输,也就是说每个 PCIe Devices 都有自己的专用连接,可以独享带宽,而不必向共享总线竞争带宽。

在这里插入图片描述

具体而言,PCIe 总线架构由以下几个部分组成:

  • PCIe Root Complex(RC,根聚合体):位于主板之上,通过 CPU Bus 与 CPU 和 Main Memory 互联,充当 CPU、Main Memory、PCIe Bus 之间通信的枢纽,并实现各类外设总线的聚合。

  • PCIe Switch:作为 PCle Hub and Switch,连接 PCIe RC 和多个 PCIe Devices,使得 PCIe Bus 具有良好的扩展性。

  • PCIe Endpoint:接入到 PCIe Bus 上的 PCIe Device,可以分为 2 种类型:

    1. Lagacy PCl-E Endpoint:指兼容 PCIe 标准的 PCI / PCI-X Device。
    2. Native PCl-E Endpoint:指标准的 PCle Device。
  • PCI/PCI-X Bridge:作为 PCI/PCI-X Bus 和 PCIe Bus 之间的桥接,以此支持标准的 PCI/PCI-X Devices。

在这里插入图片描述

PCIe 总线的工作原理如下:

  1. PCIe Root Complex 发送一个 TLP(Transaction Layer Packet,事务层数据包)到 PCIe Bus。
  2. PCIe Switch 接收 TLP 并进行路由,将 TLP 转发到 Target PCIe Device。
  3. PCIe Device 接收到 TLP 后返回 TLP Response。
  4. PCIe Switch 接收 TLP Response 后返回给 PCIe Root Complex。

PCIe 外设

  • PCIe 设备的接口类型
    在这里插入图片描述

  • PCIe 设备的体积类型

    • LP(半高)
    • FH(全高)
    • HL(半长)
    • FL(全长)
    • SW(单宽)
    • DW(双宽)
  • PCIe 设备的插槽:PCIe Bus 支持对 PCI/PCI-X Bus 的软件兼容,但主板上的接口插槽却不兼容,因为 PCIe 是串行接口,针数会更少,插槽会更短。
    在这里插入图片描述

PCIe 设备的枚举过程

PCIe Bus 是一个树状结构,所以 PCIe Devices 的枚举算法采用了深度优先遍历算法,即:对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。

  1. 主机起电后,操作系统首先扫描 Bus0(Root Complex 与 Host Bridge 相连的 PCIe Bus 定为 Bus0)。随后发现 Bridge1,将 Bridge1 下游的 PCIe Bus 定为 Bus1。初始化 Bridge 1 的配置空间,并 Bridge1 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 0 和 1,表明 Bridge1 的上游总线是 Bus0,下游总线是 Bus1。由于还无法确定 Bridge1 下挂载设备的具体情况,系统先暂时将 Subordinate Bus Number 设为 0xFF。
    在这里插入图片描述

  2. 操作系统开始扫描 Bus1。随后发现 Bridge3,并识别为一个 PCIe Switch 类型。系统将 Bridge3 下游的 PCIe Bus 定为 Bus 2,并将 Bridge3 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 1 和 2。一样暂时把 Bridge3 的 Subordinate Bus Number 设为 0xFF。
    在这里插入图片描述

  3. 操作系统继续扫描 Bus2。随后发现 Bridge4。继续扫描,随后发现 Bridge4 下面挂载了 NVMe SSD 设备。将 Bridge4 下游的 PCIe Bus 定为 Bus3,并将 Bridge4 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 2 和 3。另外,因为 Bus3 下游是 PCIe Endpoint,不会再有下游总线了,因此 Bridge4 的 Subordinate Bus Number 的值可以确定为 3。
    在这里插入图片描述

  4. 完成 Bus3 的扫描后,操作系统返回到 Bus2 继续扫描,随后发现 Bridge5。继续扫描,随后发现 Bridge5 下面挂载的 NIC 设备。将 Bridge5 下游的 PCIe Bus 设置为 Bus4,并将 Bridge5 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 2 和 4。另外,同样因为 Bus4 上挂在的是 PCIe Endpoint,所以 Bridge5 的 Subordinate Bus Number 的值可以确定为 4。
    在这里插入图片描述

  5. 除了 Bridge4 和 Bridge5 以外,Bus2 下面已经遍历完毕,因此返回到 Bridge3。因为 Bus4 是挂载在 Bridge3 下游的最后一个 Bus Number,所以将 Bridge3 的 Subordinate Bus Number 设置为 4。Bridge3 的下游设备都已经扫描完毕,继续返回到 Bridge1,同样将 Bridge1 的 Subordinate Bus Number 设置为 4。
    在这里插入图片描述

  6. 系统返回到 Bus0 继续扫描,会发现 Bridge2,将 Bridge2 下游的 PCIe Bus 定为 Bus5。并将 Bridge2 的 Primary Bus Number 和 Secondary Bus Number 寄存器分别设置成 0 和 5。由于 Graphics Card 也是 PCIe Endpoint,因此 Bridge2 的 Subordinate Bus Number 的值可以确定为 5。

至此,系统完成了对 PCIe Bus 的扫描,将 PCIe Devices 都枚举了出来,操作系统通过这一过程获得了一个完整的 PCIe 设备拓扑结构。

在这里插入图片描述

PCIe 设备的编址方式

BDF(Bus-Device-Function)编号

CPU 要访问一个 PCIe Device 就必须要知道它的总线编号。

PCIe 标准支持在一台 Host 上创建最多 256 个 PCIe Bus,每条 Bus 最多可以支持 32 个 PCIe Device,每个 Device 最多可以支持 8 个 Functions。所以 PCIe 设备的总线编号由 Bus Number(范围是 0~255)、Device Number(范围是 0~31)、Function Number(范围是 0~7)这 3 个部分组成,简称 BDF。

例如:BDF 0000:01:00.0 表示位于 Bus0、Device1、Func0 的 PCIe 设备。

在这里插入图片描述

BAR(Base Address Register)地址

CPU 除了需要支持 PCIe Device 得 BDF 之外,还需要从 PCIe Device 的 BAR(Base Address Register,基地址寄存器)知道它所拥有的内存空间的地址范围。Device 的 Driver 需要通过 “基地址+寄存器偏移量“ 的方式来访问 Device 的内存空间并完成相应的配置操作。

下图是一个 PCIe Device 的内存配置空间,具有 6 个 BARs,分布在 0x0010 ~ 0x0028 这 24Bytes 中。在操作系统启动时,就会将这些 BARs 完成解析,并以文件系统的方式供用户态 Application 读取。

在这里插入图片描述

更进一步的,PCIe Device 会根据不同的目录将这 6 个 BARs 划分为不同的 Region,以 Intel 82599 网卡为例子。其拥有的 6 个 BAR 被分成了 3 块 Regions,各占 64bits:

  1. Memory BAR:指向 Main Memory 的一个地址,表示数据存储空间,对应 Device Memory。支持进行 mmap() 映射,如果 Application 希望操作 PCIe 设备,就必须 mmap() 这个地址空间。

  2. I/O BAR:指向 Main Memory 的一个地址,表示 I/O 空间,对应 Device Register。Application 需要通过专门的操作接口来进行读写。

  3. MSI-X BAR:指向 Main Memory 的一个地址,表示 MSI-X 空间。用来配置 MSI-X 中断向量。

在这里插入图片描述

在有了 Memory BAR 和 I/O BAR 之后,CPU 就可以通过 2 种不同的方式来访问 Device 了。其中 Memory BAR 是必须的,而 IO BAR 是可选的。

  1. 通过 I/O 空间,结合专用的 CPU 指令进行访问。例如:in、out 指令。Intel x86 CPU 的 in、out 的语法如下:
IN 累加器, {端口号 | DX}
OUT {端口号 | DX}, 累加器
  1. 通过 Memory 空间,进行数据读写,实现上更加容易。

在这里插入图片描述

下面以 Memory BAR 为例,介绍 Application 访问 Device 的流程。PCIe Device 的 Memory 空间关联到 PF Memory,存放的是 PF 的控制与状态信息。以 NVMe 为例,对 NVMe 的控制以及获取其工作状态都可以通过访问它的 Memory 空间来实现。

NVMe 命令下发的基本操作是:

  1. Host 写 doorbell 寄存器,此时使用 PCIe Memory 写请求。如下图所示,Host 发出一个 MWr(Memory Write)请求,该请求经过 PCIe Switch 到达要访问的 NVMe SSD 设备。

在这里插入图片描述

  1. NVMe 读取命令操作,这个请求会被 PCIe Endpoint 接收并执行。如下图所示,此时 NVMe SSD 作为请求者,发出一个 MRd(Memory Read)请求,该请求经过 PCIe Switch 到达 Host CPU。Host CPU 作为完成者会返回一个 CplD(事务完成包),将访问结果返回给 NVMe SSD。

在这里插入图片描述

同样,NVMe 的其他操作都是通过 PCIe Memory 访问的方式来进行的。

Linux 上的 PCIe 设备

如下图,查看 Linux 操作系统上的一个 PCIe 设备,具有以下文件:

  • config:设备的配置空间,二进制,可读写。
  • device:设备的 Device ID,只读。
  • vendor:设备的 Vendor ID,只读。
  • driver:设备驱动程序的目录。
  • enable:设备是否正常使能,可读写;
  • irq:设备分到的中断号,只读;
  • local_cpulist:和设备处于同一个 NUMA Node 的 CPU 清单,用于实现 NUMA 亲和性。
  • local_cpu:和 local_cpulist 的作用一样,以掩码的方式给出。
  • numa_node:设备所属的 NUMA node,只读。
  • resource:设备的 BARs 记录,只读。
  • resource0…N:某个 BAR 空间,二进制,只读。
  • sriov_numfs:设备的 VFs 数量。
  • sriov_totalvfs:与 sriov_numfs 作用相同。
  • subsystem_device:PCIe 子系统设备 ID,只读。
  • subsystem_vendor:PCIe 子系统厂商 ID,只读。

在这里插入图片描述

查看 PCIe 设备的 BDF

下图黄色方框中的 PCIe 设备是 Bejing Starblaze Technology Co., LTD. 推出的 STAR1000 系列 NVMe SSD 设备,其中 9d32 是 Starblaze 在 PCI-SIG 组织的注册码,1000 是设备系列号。

STAR1000 的 BDF 分别为 0x3C、0x00、0x0,即:3C:00.0,与之对应的上游端口是 00:1d.0。

在这里插入图片描述

查看 PCIe 设备的 Vendor ID 和 Device ID

下图可以看到一个 NVMe Controller 的详细信息:

  • Vendor ID:供应商识别字段,由 PCI SIG 分配。
  • Device ID:设备识别字段,由供应商分配。
  • Class Code:表示这是一个 NVMe SSD 设备。
  • First Capability Pointer:指向 Device Capability 的入口,从 0x40 地址开始依次是 Power management、MSI 中断、链路控制与状态、MSI-X 中断等特性组。

在这里插入图片描述

查看 PCIe 设备的详细信息

下图中展示了指定 PCIe 设备的详细信息。其中可以看见该设备的 Memory BAR 空间,一段的大小是 1MB,另一段的大小是 256KB。系统可以通过 Memory 空间访问设备。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283610.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法强化--两数之和

hi,大家好,今天为大家带来一道题目,求两数之和 题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一…

Python 进阶指南(编程轻松进阶):三、使用 Black 工具来格式化代码

原文:http://inventwithpython.com/beyond/chapter3.html 代码格式化是将一组规则应用于源代码,从而使得代码风格能够简洁统一。虽然代码格式对解析程序的计算机来说不重要,但代码格式对于可读性是至关重要的,这是维护代码所必需的…

【剑指offer|4.从尾到头打印单链表】

0.从尾到头打印单链表 单链表:一般给的都是无头节点的 另外:在面试中,如果我们打算修改输入的数据,则最好问一下面试官是不是允许修改 下面这种先把链表节点的值按链表序放到数组中,然后来一个算法库中的reverse属实有…

一文懂KL散度KL Divergence

本文翻译自https://naokishibuya.medium.com/demystifying-kl-divergence-7ebe4317ee68 KL散度中的KL全称是Kullback-Leibler,分别表示Solomon Kullback和Richard A.Leibler这两个人。 一、KL散度的定义 KL散度表明概率分布Q和概率分布P之间的相似性,由…

ARM Linux 内核启动1 —— 汇编阶段

一、Makefile分析 1、Makefile 分析 (1) kernel 的 Makefile 写法和规则等,和 uboot 的 Makefile 是一样的,甚至 Makefile 中的很多内容都是一样的。 (2) kernel 的 Makefile 比 uboot 的 Makefile 要复杂,这里我们并不会一行一行的详细分析…

【20】核心易中期刊推荐——计算机科学电子通信(EI索引)

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

进阶C语言:文件操作

文件操作不仅仅是我们使用鼠标用来操作文件的各项功能,还可以使用C语言来操作文件的内容,可以使用C语言来对文件的读、写、拷贝...等等,话不多说,直接开始: 目录 1.为什么要使用文件 2.什么是文件 2.1程序文件 2.…

蓝桥杯【第14届省赛】Python B组

本题解不一定正确,欢迎大家指正 A:2023 【问题描述】 请求出在 12345678 至 98765432 中,有多少个数中完全不包含 2023 。 完全不包含 2023 是指无论将这个数的哪些数位移除都不能得到 2023 。 例如 20322175,33220022 都完全不包…

python实现获取当前目录下的树形结构

python实现获取当前目录下的树形结构 程序实现 在有些Linux上自带了tree命令来一树状结构显示一个目录,但是在有些linux上没有自带这个程序,所以这里用python写了一个小程序来实现这个功能,代码如下: import osdef print_tree(…

共模电感(扼流圈) 差模电感(扼流圈)

共模电感 共模电感,也叫共模扼流圈。常用于电脑的开关电源,过滤共模的电磁干扰信号。 共模电感器由软磁铁芯(铁氧体磁芯)和两组同相绕制的线圈组成。对于共模信号,由于两组线圈产生的磁场不是抵消。而是相互叠加&…

存量市场之下,电商之战深入腹地且逻辑未变

纵然是在流量依然见顶的大背景下,电商行业的竞争并未结束。无论是以百亿补贴为代表的烧钱策略,还是以跨境出海为代表的规模策略,几乎都是这样一种现象的直接体现。种种迹象表明,未来的电商行业,依然会有新的战役发生。…

Hadoop集群环境搭建与应用回顾

文章目录一、 实训项目名称二、 学习情况小结三、 项目中用到的知识点四、 实训项目中负责功能板块五、 实训项目实现六、 实训项目过程中遇到的问题及解决方法七、实训体会与心得一、 实训项目名称 Hadoop集群环境搭建与应用 二、 学习情况小结 实操一部分: 通…

linux 服务器 docker 安装 nacos 2.0.3

docker 镜像 https://registry.hub.docker.com/r/nacos/nacos-server/tags 1.下载nacos镜像 这里下载的是2.0.3 docker pull nacos/nacos-server:2.0.32.查看镜像是否下载成功 如下图 docker images3.创建文件夹 注: 自定义创建,用于把docker内部的文件…

【基金学习】基金的相关计算题目

文章目录一、基金收益计算1. 累计收益/持有收益2. 年化收益/年化收益率3. 涨跌幅4. 分红二、风险计算1. 贝塔系数2. 波动率三、费用计算1. 托管费2. 管理费3. 销售服务费4. 申购/赎回费一、基金收益计算 1. 累计收益/持有收益 累计收益 持仓金额 - 本金 累计收益率 &#xf…

TCP 的 NACK 与 SACK

可靠传输,一旦丢包,必然 HoL blocking,NACK 和 SACK 必须二选一驱动重传: NACK:receiver 主动通告没有收到的报文,sender 收到后重传。 SACK:receiver 主动通告收到的报文,sender …

一文带你深入了解算法笔记中的前缀与差分(附源码)

📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段,因为最近参加新星计划算法赛道(白佬),所以加快了脚步,果然急迫感会增加动力>——…

笔记本上就能跑的 LLM 好使吗?GPT4ALL 体验

是骡子是马,牵出来遛遛正名看到这个标题,你可能会觉得是噱头。谁不知道 ChatGPT 模型有 1750 亿以上的参数,别说是在笔记本电脑上跑,就是使用高性能 GPU 的台式机,也无法带得动啊。老老实实调用 API 不好吗&#xff1f…

torchvision.transforms 常用方法解析(含图例代码以及参数解释)

本文代码和图片完全源于 官方文档: TRANSFORMING AND AUGMENTING IMAGES 中的 Illustration of transforms,参数介绍源自函数对应的官方文档。 代码中的变换仅仅使用了最简单的参数:pad,size 等,这里展现的只是简单的变换&#xf…

中间表示- 数据流分析

数据流分析往往与优化绑定在一起,如下图所示。 优化的一般模式 程序分析 (1)控制流分析、数据流分析、依赖分析等。 (2)得到被优化程序的静态保守信息,是对动态运行行为的近似。 程序重写 以上一步得到…

用于3D分子生成的等变扩散模型ICML2022

现代深度学习方法开始对分子科学产生重要影响。在Alphafold在蛋白质折叠预测方面取得成功的背后,越来越多的工作开发了深度学习模型来分析或合成分子。分子存在于物理3D空间中,因此受制于几何对称性,如平移、旋转。这些对称性被称为三维欧几里…