目录
一、PCI:并行总线的经典时代1.1 产生1.2 组成结构与种类划分1.3 总结
二、PCIe:串行高速总线的革命2.1 产生2.2 特点2.3 嵌入式 ARM Linux 中的典型应用
三、从软件开发角度看待PCI和PCIe3.1 参考资料3.2 最容易访问的设备是什么3.3 理解PCI和PCIE的关键3.4 访问PCI/PCIe设备的流程
四、Linux系统中操作PCIE相关命令4.1 `lspci` - 列出PCI/PCIe设备信息4.2 `setpci` - 查询和配置PCI/PCIe设备4.3 驱动开发要点
一、PCI:并行总线的经典时代
1.1 产生
PCI(Peripheral Component Interconnect,外设部件互连标准)是 一种由英特尔(Intel)公司1991年推出的用于定义局部总线的标准。此标准允许在计算机内安装多达10个遵从PCI标准的扩展卡。
它是个人电脑中使用最为广泛的接口,几乎所有的主板产品上都带有这种插槽。PCI插槽也是主板带有最多数量的插槽类型,在流行的台式机主板上,ATX结构的主板一般带有5~6个PCI插槽,而小一点的MATX主板也都带有2~3个PCI插槽,可见其应用的广泛性。(ATX(Advanced Technology eXtended)结构是一种广泛应用于个人计算机的主板结构规范,由英特尔公司在1995年提出)
PCI总线是由ISA(Industy Standard Architecture)总线发展而来的,ISA并行总线有8位和16位两种模式,时钟频率为8MHz,工作频率为33MHz/66MHz。是一种同步的独立于处理器的32位或64位局部总线。从结构上看,PCI是在CPU的供应商和原来的系统总线之间插入的一级总线,具体由一个桥接电路实现对这一层的管理,并实现上下之间的接口以协调数据的传送。从1992年创立规范到如今,PCI总线已成为了计算机的一种标准总线。已成为局部总线的新标准,广泛用于当前高档微机、工作站,以及便携式微机。主要用于连接显示卡、网卡、声卡。
1.2 组成结构与种类划分
从数据宽度上看:PCI总线有32bit、64bit之分;
从总线速度上分:有33MHz、66MHz两种。
目前流行的是32bit @ 33MHz,而64bit系统正在普及中。改良的PCI系统,PCI-X,最高可以达到64bit @ 133MHz,这样就可以得到超过1GB/s的数据传输速率。
以32bit @ 33MHz为例。PCI总线是32位同步复用总线。其地址和数据线引脚是AD31~AD0。PCI的工作频率为33MHz。
在处理器系统中,含有PCI总线和PCI总线树这两个概念。这两个概念并不相同,在一颗PCI总线树中可能具有多条PCI总线,而具有血缘关系的PCI总线组成一颗PCI总线树。PCI总线由HOST主桥或者PCI桥管理,用来连接各类设备,如声卡、网卡和IDE接口卡等。
在一个处理器系统中,可以通过PCI桥扩展PCI总线,并形成具有血缘关系的多级PCI总线,从而形成PCI总线树型结构。在处理器系统中有几个HOST主桥,就有几颗这样的PCI总线树,而每一颗PCI总线树都与一个PCI总线域对应。与HOST主桥直接连接的PCI总线通常被命名为PCI总线0。考虑到在一个处理器系统中可能有多个主桥。
更多细节知识请阅读百度百科:PCI总线
1.3 总结
总线结构
共享并行总线:所有设备挂载在同一总线上,通过仲裁器竞争访问权限。带宽限制:32位/33 MHz 版本带宽仅 133 MB/s(64位/66 MHz 提升至 533 MB/s)。物理接口:使用多根数据线(32/64位)和边带信号(如中断请求线)。 拓扑结构
菊花链拓扑:设备串联连接,总线扩展需通过PCI桥芯片。 局限性
带宽瓶颈:多设备共享带宽,高速设备(如显卡)性能受限。时钟同步难题:并行信号在高频下易受干扰,66 MHz 已是物理极限。热插拔支持弱:需额外标准(如 PCI Hot-Plug)实现,兼容性差。
二、PCIe:串行高速总线的革命
2.1 产生
PCI-Express(peripheral component interconnect express)是一种高速串行计算机扩展总线标准,它原来的名称为“3GIO”,是由英特尔在2001年提出的,旨在替代旧的PCI,PCI-X和AGP总线标准。PCIe交由PCI-SIG(PCI特殊兴趣组织)认证发布后才改名为“PCI-Express”,简称“PCI-e”。它的主要优势就是数据传输速率高,而且还有相当大的发展潜力。
2.2 特点
PCIe属于高速串行点对点双通道高带宽传输,所连接的设备分配独享通道带宽,不共享总线带宽,主要支持主动电源管理,错误报告,端对端的可靠性传输,热插拔以及服务质量(QOS)等功能。
PCI Express也有多种规格,从PCI Express x1到PCI Express x16,能满足将来一定时间内出现的低速设备和高速设备的需求。
更多细节知识请阅读百度百科:PCI-E
PCI(Peripheral Component Interconnect)和 PCIe(PCI Express)是计算机系统中用于连接外设的总线标准,两者虽有继承关系,但在架构、性能和用途上存在本质差异。以下从核心特性、技术演进和应用场景三方面进行对比解析:
核心革新
点对点串行架构
差分信号传输:每组 Lane 含 2 对差分线(TX/RX),抗干扰能力强。可扩展链路宽度:支持 ×1、×2、×4、×8、×16 配置(如显卡用 ×16)。全双工通信:发送与接收通道独立,双向传输互不干扰。 分层协议栈
层级功能描述事务层数据包封装(TLP:Transaction Layer Packet)数据链路层错误校验与重传(ACK/NACK)物理层串行化/解串行化(SerDes) 性能飞跃
关键差异对比
特性PCIPCIe传输方式并行总线(共享带宽)串行点对点(独享通道)拓扑结构总线型/菊花链树状交换拓扑(支持 Switch)热插拔需额外支持原生支持(PCIe Hot-Plug)中断机制INTx 引脚中断MSI/MSI-X(内存写入消息)电源管理基础 SMM(S3/S4)主动状态管理(ASPM L0s/L1)应用场景低速设备(声卡、网卡)高速设备(GPU、NVMe SSD)
2.3 嵌入式 ARM Linux 中的典型应用
NVMe SSD:通过 M.2 接口连接高速存储(×4 链路)。FPGA 加速卡:实现定制硬件加速(如 AI 推理)。多网口扩展:工业网关中连接多个 10G 网卡。外部GPU:理论上通过将主控板与任何PCIe桌面显卡(封装在自己的外部外壳中,具有强大的电源和散热)连接,外部PCIe可以为主控板提供更强大的算力。
三、从软件开发角度看待PCI和PCIe
3.1 参考资料
《PCI Express Technology》,Mike Jackson, Ravi Budruk; MindShare, Inc.《PCIe扫盲系列博文》,作者Felix,这是对《PCI Express Technology》的理解与翻译《PCI EXPRESS体系结构导读 (王齐)》《PCI Express_ Base Specification Revision 4.0 Version 0.3 ( PDFDrive )》《NCB-PCI_Express_Base_5.0r1.0-2019-05-22》
3.2 最容易访问的设备是什么
是内存!要读写内存,知道它的地址就可以:
volatile unsigned int *p = 某个地址;
unsigned int val;
*p = val; /* 写 */
val = *p; /* 读 */
只有内存能这样简单、方便地使用吗?不是的,所有的"ram-like"接口设备都可以这样操作。什么叫"ram-like"接口?
要发出地址:有地址线要读写数据:有数据线怎么分辨是读还是写:有读写信号众多"ram-like"设备共享上面的信号,怎么才能互不影响?每个设备都有自己的片选信号
如下图所示:
CPU发出addr,到达内存控制器,也出现在RAM、Flash、GPIO等设备上使能设备:如果addr属于RAM的地址范围,cs0就被使能如果addr属于Flash的地址范围,cs1就被使能如果addr属于GPIO的地址范围,cs2就被使能没有被使能的设备,就相当于没接上去一样,不会影响其他设备读写数据关键在于:内存控制器,它会根据地址范围发出对应的片选信号,选中对应的设备。
CPU 访问emmc flash中一个地址: CPU发出addr,可以用来访问EMMC控制器,但是CPU发出的addr,不能直接到达EMMC Flash,想访问EMMC Flash必须通过EMMC控制器,EMMC控制器驱动程序进行地址转换处理;
直接访问限制:CPU可直接读写emmc控制器但无法直接访问emmc flash,必须通过控制器间接操作。驱动复杂性:根源在于CPU地址空间与flash地址空间隔离,需要编写复杂驱动程序进行信号转换。地址空间转换:若CPU地址能直接映射到flash地址空间(如PCI协议实现),则可简化访问流程。
3.3 理解PCI和PCIE的关键
传统协议缺点:如I2C需要手动控制多个寄存器来产生start信号、设备地址、存储地址等,流程复杂
设置状态寄存器产生start信号写入数据寄存器发送设备地址+读写位写入数据寄存器发送存储地址写入/读取数据寄存器 产生stop信号 PCI协议优势:硬件自动完成地址转换和信号生成,开发者只需关注最终数据读写。 空间分配机制:
设备通过配置空间声明所需PCI地址空间大小(如1MB)主机读取声明后分配对应PCI地址范围(如A~B)设置PCI控制器完成CPU地址到PCI地址的偏移转换
地址空间转换: PCI接口速览:
地址数据复用:PCI接口使用AD0-AD31共32根线复用传输地址和数据,通过FRAME信号区分传输阶段。关键控制信号:
FRAME:标识传输开始和地址阶段DEVSEL:设备选择信号IRDY/TRDY:发起方和目标方就绪信号PAR:奇偶校验信号 并行接口局限:当速率提高时,并行信号线间会产生严重干扰,制约了性能提升空间。
PCIE 接口速览:
串行差分传输:PCIE采用差分信号对(T+/T-和R+/R-)进行高速串行传输,解决了并行接口的干扰问题。信号编码方式:将地址和数据信息编码到串行数据流中,通过接收端解码还原。关键差分信号:
PCIe_TXP/PCIe_TXN:发送差分对PCIe_RXP/PCIe_RXN:接收差分对PCIe_REFCLKP/PCIe_N:参考时钟 软件兼容性:虽然物理层不同,但PCIE在软件层面保持与PCI兼容,程序仍通过内存地址方式访问设备。地址转换机制:CPU发出的地址由PCIE控制器转换为PCIE地址空间,再通过串行链路传输给设备。
3.4 访问PCI/PCIe设备的流程
PCI/PCIe设备的配置信息:PCI/PCIe设备上有配置空间(配置寄存器),用来表明自己"需要多大的地址空间"。注意,这是PCI/PCIe地址空间。主机读取设备配置信息、分配空间:主机上的程序访问PCI/PCIe设备,读出配置信息。分配地址空间:注意,分配的是PCI/PCIe地址空间。把地址空间首地址写入设备。CPU地址空间和PCI/PCIe地址空间转换:在PCI/PCIe控制器中,有某个寄存器用来保存offset值。假设CPU发出的addr_cpu,是用来访问PCI设备的,转换关系为:
addr_pci = addr_cpu + offset
主机像读写内存一样访问设备:
volatile unsigned int *p = addr_cpu;
unsigned int val;
*p = val; /* 写, 硬件会把addr_cpu转换为addr_pci去写PCI/PCIe设备 */
val = *p; /* 读, 硬件会把addr_cpu转换为addr_pci去读PCI/PCIe设备 */
四、Linux系统中操作PCIE相关命令
busybox应该是有一个自带的简化版lspci,并不是完整的pciutils程序。可以自行编译pciutils程序:lspci & setpci 工具编译及使用。
4.1 lspci - 列出PCI/PCIe设备信息
lspci命令用于显示连接到PCI和PCIe总线的所有设备。这个命令由pciutils包提供,适用于基于Linux和BSD的操作系统。
基本用法:
lspci
这将列出所有PCI/PCIe设备的信息,包括厂商ID、设备ID、设备类别、修订号等。
高级选项:
-s: 后面跟随设备编号,用于显示特定设备的详细信息。-v: 显示详细信息(verbose)。-x: 显示设备的配置空间的十六进制转储(hex-dump)。-vv: 显示非常详细的信息(very verbose)。-D: 测试模式,不真正写入配置信息,用于模拟操作。
实例: lspci -vt命令可以显示系统的PCIe拓扑图,这对于理解设备之间的连接关系非常有用。这将显示一个树状结构,其中包括域(Domain)、总线(Bus)、设备(Device)和功能(Function)的编号。
4.2 setpci - 查询和配置PCI/PCIe设备
setpci命令是一个查询和配置PCI/PCIe设备的工具。它可以用来修改设备的某些属性,例如,调整笔记本屏幕亮度。
基本用法:
setpci (选项) (参数)
其中,选项和参数的具体内容如下:
选项:
-v: 显示指令执行的细节信息。-f: 当没有任何操作需要完成时,不显示任何信息。-D: 测试模式,并不真正将配置信息写入寄存器。-d: 仅显示给定厂商和设备的信息。-s: 仅显示指定总线、插槽上的设备或设备上的功能块信息。
参数:
PCI设备: 指定要配置的PCI/PCIe设备。操作: 指定要完成的配置操作。
实例: 假设要调整笔记本屏幕亮度,首先使用lspci命令找到VGA设备的地址,然后使用setpci命令修改其属性:
setpci -s 00:02.0 F4.B=FF
这里,-s 00:02.0指定了设备的地址,F4.B=FF是修改的长度和值。不同的电脑可能有不同的属性地址和值,需要根据实际情况调整。
注意事项
使用lspci和setpci命令时,可能需要管理员权限,因此可能需要在命令前加上sudo。修改PCIe设备配置时要小心,错误的操作可能会导致系统不稳定或设备损坏。在执行任何配置更改之前,建议备份当前的配置,以便在出现问题时可以恢复。
4.3 驱动开发要点
设备枚举:内核自动扫描 PCIe 拓扑,生成 /sys/bus/pci/devices/。资源配置:通过设备树声明控制器参数(内存映射、时钟、中断)。DMA 优化:使用 dma_alloc_coherent() 避免 Cache 一致性问题。遗留 PCI 的兼容性 - 桥接方案:部分 ARM SoC 通过 PCIe-to-PCI 桥片支持老设备(如工控 legacy 卡)。 - 驱动兼容:Linux 内核中 PCIe 设备仍使用 pci_driver 框架(需注意 MSI 中断处理差异)。
欢迎阅读下一篇:PCI设备的访问方法