【问题标题】:PCI-e memory space access with mmap使用 mmap 访问 PCI-e 内存空间
【发布时间】:2017-03-16 16:00:35
【问题描述】:

我在 Freescale MPC8308 处理器(基于 PowerPC 架构)上使用 PCI-e 端口,但在尝试使用它时遇到了一些问题。端点 PCI-e 设备的内存空间等于 256 MB。我可以使用“pciutils”包轻松读写端点设备的配置空间。

在配置寄存器中写入正确的值并获得访问内存空间的权限后;我尝试使用 C 中的“mmap()”函数访问内存空间,并使用位于:

的文件描述符

"/sys/devices/pci0000:00/0000:00:00.0/resource0"

正好是 256 MB(等于端点设备的内存空间),所以我似乎使用了正确的文件描述符路径。在这里您可以使用https://github.com/billfarrow/pcimem 中提到的“mmap()”找到我的代码:

https://github.com/billfarrow/pcimem/blob/master/pcimem.c

但不幸的是,当我尝试使用“mmap()”函数的返回地址来使用内存空间时;我无法正确读取端点设备的只读寄存器。此外,当我读取大于“0x7FFFFFC”的地址时,MPC8308 会重新启动。 考虑到上述情况,我是否错过了初始化 PCI-e 接口的任何步骤?我应该更改 Linux 内核映像或 U-Boot 代码中的任何内容吗?将 PowerPC PCI-e 与 mmap() 一起使用有什么不同吗?你有任何示例代码可以帮助我读取 PCI-e 内存空间吗?

谢谢

【问题讨论】:

  • 端点的 256MB 内存空间似乎太大了。在我的处理器 (i.MX6) 上,我的端点不能大于 16MB。您在 Linux 引导 PCIe 时遇到初始化错误吗?您的 PCI-e 存储设备是什么?是 FPGA 吗?
  • 是的,这对我来说似乎太多了,但我在 Linux 启动中没有任何错误,并且它为设备分配了 256 MB 的内存,正如我在 /proc/iomem 中看到的那样。端点设备不是 FPGA。它是一个带有 PCI-e 接口的 ASIC。
  • 另一种方法是找到设备的基本物理地址及其限制,并映射到 /dev/mem。 (老实说,不能保证这会奏效。我很好奇它是否有效。)

标签: linux mmap pci-e memory-mapping


【解决方案1】:

mmap() 是一种从用户空间访问 PCIe 设备的非常有用但随意的方法。

我注意到您将 0 作为第一个参数传递给 mmap。在我将 FPGA 卡插入 x86 计算机的情况下,我调用 lspci 以获取卡在 pcie 插槽中的物理地址。然后我使用该物理地址作为 mmap 的第一个参数。我知道您正在设备的配置空间中编写 BAR,但可能会使用 lspci 仔细检查。

$ sudo lspci -s 02:00 -v
02:00.0 Memory controller: Xilinx Corporation Device 8028
    Subsystem: Xilinx Corporation Device 0007
    Flags: bus master, fast devsel, latency 0, IRQ 11
    Memory at f7e00000 (32-bit, non-prefetchable) [size=1M]
    Capabilities: [80] Power Management version 3
    Capabilities: [90] MSI: Enable- Count=1/1 Maskable- 64bit+
    Capabilities: [c0] Express Endpoint, MSI 00
    Capabilities: [100] Advanced Error Reporting

【讨论】:

  • mmap 的第一个参数确定调用 mmap 的进程中生成的映射的虚拟地址。为什么需要将其设置为设备 BAR 的物理地址?
猜你喜欢
  • 1970-01-01
  • 2018-03-27
  • 2015-01-04
  • 2016-07-18
  • 1970-01-01
  • 2012-07-06
  • 2016-03-10
  • 1970-01-01
  • 2018-05-07
相关资源
最近更新 更多