【deepseek】PCIe BAR 的各种性质
PCIe BAR 的性质可以从多个维度进行划分,每种性质都直接决定了系统如何与设备进行通信。系统软件通过解析这些 BAR 的性质,才能正确、安全、高效地为设备分配资源并驱动它工作。好的,我们来详细解析 PCIe BAR 的各种性质,并深入探讨其背后的原理和作用。这是最根本的分类,决定了 BAR 映射到 CPU 的哪种地址总线上。这不是一个可配置的“位”,而是由 BAR 申请的大小决定的硬件约束。,
·
好的,我们来详细解析 PCIe BAR 的各种性质,并深入探讨其背后的原理和作用。
PCIe BAR 的性质可以从多个维度进行划分,每种性质都直接决定了系统如何与设备进行通信。
1. 按地址空间类型划分
这是最根本的分类,决定了 BAR 映射到 CPU 的哪种地址总线上。
- 原理:CPU 通过两种主要的地址空间访问外设:
- 内存地址空间:与访问系统 RAM 使用相同的指令(如
MOV)。地址通过内存管理单元(MMU)转换,可被缓存。 - I/O 地址空间:x86 等架构特有的独立地址空间,使用专门的指令(如
IN/OUT)访问,通常不经过缓存。
- 内存地址空间:与访问系统 RAM 使用相同的指令(如
- 作用:
- Memory BAR:现代 PCIe 设备的绝对主流选择。它允许 CPU 像访问内存一样直接读写设备的寄存器或缓冲区,编程模型简单高效,且支持 64 位大地址和预取等高级特性。
- I/O BAR:主要用于兼容古老的 PCI 设备(如传统串口、并口控制器)。在现代系统中,由于其地址空间有限(仅 16 位有效,64KB)、访问效率低于内存映射,且不被所有 CPU 架构(如 ARM)支持,因此在新设计中已基本被淘汰。
2. 按位宽划分
此性质定义了 BAR 所能寻址的范围大小。
- 原理:
- 32 位 BAR:使用配置空间中的 1 个双字(4 字节)。其低 4 位用于编码类型,高 28 位用于存储基地址,因此最大可映射 256MB 的连续空间(2^28)。实际中,操作系统通常限制其最大为 4GB。
- 64 位 BAR:使用配置空间中两个连续的双字(共 8 字节)。第一个双字的低 4 位编码类型为“64位”,第二个双字与第一个的高位共同组成 64 位基地址。这允许设备申请巨大的地址空间(理论上 2^64)。
- 作用:
- 32 位 BAR:适用于寄存器组或小容量缓冲区。对于需要大于 4GB 地址的系统,32位地址已不够用。
- 64 位 BAR:满足高性能设备对大容量、直接可寻址内存的需求。最典型的应用是显卡的显存(VRAM)。现代 GPU 拥有数GB乃至数十GB的显存,这些显存通过一个巨大的 64 位 Prefetchable Memory BAR 映射到系统的物理地址空间,GPU驱动和CPU可以直接通过这个窗口读写显存,这是实现高性能图形处理和 GPGPU 计算的基础。
3. 按预取属性划分
这是 Memory BAR 独有的关键性质,决定了系统总线、CPU缓存能否优化对该区域的访问。
- 原理:
- 预取 和 缓存 是 CPU 提升内存访问性能的核心技术。它们基于一个假设:对内存的读取操作是无副作用的,即多次读取同一地址返回相同数据,且不会改变设备状态。
- Non-prefetchable(不可预取):当 BAR 的
Prefetchable位为 0 时,表示该内存区域读取可能有副作用。例如,读取一个设备的状态寄存器可能会清除其中的“中断待处理”标志。如果 CPU 缓存了该值,后续读取将得到陈旧数据,导致驱动程序无法感知状态变化,系统行为错误。因此,系统硬件必须禁止对该区域的缓存和预取,每次访问都必须“直达”设备。 - Prefetchable(可预取):当
Prefetchable位为 1 时,表示该内存区域读取无副作用,写入通常是缓冲式的(如写入帧缓冲区)。系统可以安全地对该区域进行读合并、预取、缓存等优化,极大提升访问吞吐量。
- 作用:
- Non-prefetchable Memory BAR:用于映射设备的控制寄存器、状态寄存器、命令队列等。确保每次读写都能及时、准确地与设备交互。
- Prefetchable Memory BAR:用于映射设备的大数据缓冲区,如显卡的显存、高性能网卡的 DMA 缓冲区、NVMe SSD 的控制器内存缓冲区(CMB)等。这允许 CPU 和 DMA 引擎以最高效的方式搬运数据。
4. 按地址对齐性质
这不是一个可配置的“位”,而是由 BAR 申请的大小决定的硬件约束。
- 原理:在系统软件(BIOS/OS)为 BAR 分配地址时,它通过 “写全1读回” 的机制探测设备需要多大的空间。设备在 BAR 中返回一个位掩码,其中低位为 0 的位表示地址的固定部分。
- 例如,一个设备需要 16KB (0x4000 字节) 的空间。16KB 是 2^14 字节,所以地址的低 14 位(bit[13:0])必须在设备内部用于寻址。设备会在 BAR 中返回一个掩码,其中 bit[13:0] = 0,bit[31:14] = 可写。系统读回后,就知道必须分配一个 16KB 对齐(即起始地址是 0x4000 的整数倍)的地址块。
- 作用:
- 简化设备内部地址解码:设备只需用 BAR 分配来的基地址的高位与自己内部地址偏移量的低位简单拼接,就能得到完整的物理地址,无需复杂计算。
- 保证空间连续性:强制对齐确保了分配的地址块是一个完整、连续的区间,不会与其他设备空间重叠。
总结与关联
| 性质维度 | 主要类型 | 原理核心 | 典型作用 |
|---|---|---|---|
| 地址空间 | Memory BAR | 映射到统一内存空间,使用内存指令访问 | 现代设备标准接口,用于寄存器和缓冲区 |
| I/O BAR | 映射到独立I/O空间,使用专用指令 | 传统设备兼容,现代设计已弃用 | |
| 位宽 | 32-bit BAR | 单寄存器,寻址范围有限 | 小规模寄存器集 |
| 64-bit BAR | 双寄存器,寻址范围巨大 | 大容量设备内存(如GPU显存) | |
| 预取属性 | Non-prefetchable | 读取有副作用,禁止缓存/预取 | 控制/状态寄存器,确保访问准确性 |
| Prefetchable | 读取无副作用,允许缓存/预取 | 大数据缓冲区,最大化传输性能 | |
| 地址对齐 | Size-defined Alignment | 由所需空间大小决定对齐边界 | 简化设备寻址,保证资源不冲突 |
一个实际的 PCIe 设备(如显卡)通常会组合使用多种 BAR:
- BAR0:一个 64 位、可预取的 Memory BAR,映射数 GB 的显存。
- BAR2:一个 32 位、不可预取的 Memory BAR,映射 GPU 的控制和状态寄存器。
系统软件通过解析这些 BAR 的性质,才能正确、安全、高效地为设备分配资源并驱动它工作。
更多推荐



所有评论(0)