【问题标题】:Where is PCI BAR0 pointing to?PCI BAR0 指向哪里?
【发布时间】:2018-10-13 23:37:28
【问题描述】:

我有一个 PCI 设备,它在 BAR0 中有一些内存地址。我想这个内存地址只是操作系统虚拟地址,它指向设备的一些物理内存。问题是它指向哪里?阅读设备的文档以及固件源代码,我注意到这个设备有一些寄存器负责设置所谓的内存窗口。我希望 BAR0 会准确地指向它们,但事实并非如此,看起来像这样:

BAR0 地址 -> 一些未知内存 -> + 0x80000 我的内存窗口

那么为什么我的内存窗口从 BAR0 指向的位置偏移了 0x80000,这个 BAR0 指向我们在哪里 + 它是由谁设置的?

谢谢

【问题讨论】:

    标签: windows operating-system pci


    【解决方案1】:

    没有。 BAR 中的地址是 BAR 开头的物理地址。这就是设备知道何时以及如何响应内存读取或写入请求的方式。例如,假设 BAR (BAR0) 的长度为 128K,基地址为0xb840 0000,那么设备将响应对这些地址中的任何一个的内存读取或写入:

    0xb840 0000
    0xb840 0080
    0xb840 1184
    0xb841 fffc
    

    到这些地址中的任何一个:

    0x5844 0000              (Below BAR)
    0xb83f 0000              (Below)
    0xb83f fffc              (Below)
    0xb842 0000              (Above BAR)
    0xe022 0000              (Above)
    

    这在原始 PCI 中更为重要,其中总线实际上是共享介质,设备可能会看到对属于其他设备的地址的请求。使用 PCI-Express 的点对点架构,只有 PCI“桥”才能看到对它们不拥有的内存地址的请求。但它仍然以完全相同的方式发挥作用。并且地址空间的低位仍然允许设备为空间的不同部分指定不同的功能/操作(如在您的设备中,创建您尝试访问的单独内存窗口)。

    现在,作为程序员如何访问 BAR 内存空间是一个不同的问题。对于几乎所有现代系统,程序进行的所有内存访问都是对虚拟地址的。因此,为了让您的内存访问到达设备,必须有一个从虚拟地址到物理地址的映射。这通常是通过页表完成的(尽管某些体系结构,如 MIPS,有一个虚拟地址空间的专用区域,该区域永久映射到物理地址空间的一部分)。

    分配虚拟地址空间以及设置页表以从该空间映射到 BAR 物理地址空间的确切机制取决于处理器和操作系统。因此,您需要分配一些虚拟地址空间,然后创建从分配空间开始到(BAR0) + 0x80000 的页表映射,以便使用您的窗口。 (我将其描述为两个步骤,但您的操作系统可能提供了一个函数调用来分配虚拟地址空间并将其映射到物理范围。)

    现在,将物理地址空间分配给设备的过程(即实际上将地址插入 BAR)通常在系统初始化的早期完成在枚举系统中安装的所有 PCI 设备时,系统 BIOS 或类似的早期启动机制。所需的地址空间大小通过查询设备来确定,然后将足够大的物理地址区域的基地址写入 BAR。

    最后一个问题:为什么您的内存窗口在设备地址空间内的偏移量为 0x80000 完全是特定于设备的,无法更笼统地回答。

    【讨论】:

    • 感谢您的详细解答。但是我仍然不明白这个 BAR 指向什么?我的意思是什么内存区域 - 基址寄存器,RAM / ROM的开头或一些用户选择的空间?更重要的是我不知道是谁决定的?所以假设我有一个写入 BAR0 的内存地址。第一个问题是谁在那里写的-操作系统或BIOS对吗?第二个问题它指向哪里以及是谁以这种方式“编程”的?
    • 该 BAR 地址是 您的计算机 物理内存空间中 PCI 卡内存已映射的位置——确切的地址通常由 BIOS 分配。如果您在不同的机器上安装了同一张卡(即使用不同的 BIOS 或其他 PCI 卡的不同组合),则可能会在该机器的地址空间内为其赋予不同的地址。 BAR 区域中包含的具体内容取决于 PCI 卡:它可能是视频 RAM、NIC 寄存器或 UART 寄存器——这由其制造商决定。
    • 我知道 PCI BAR 不是物理地址,而是bus address。物理地址和总线地址之间还有另一种地址转换。我猜这个翻译是在 PCI 桥中,由操作系统设置。见kernel.org/doc/Documentation/DMA-API-HOWTO.txt,上面写着For example, if a PCI device has a BAR, the kernel reads the bus address (A) from the BAR and converts it to a CPU physical address (B).
    猜你喜欢
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多