【问题标题】:How to read 32-bit PCI bar memory in 64-bit linux kernel environment如何在 64 位 linux 内核环境下读取 32 位 PCI 条形内存
【发布时间】:2016-12-08 04:54:18
【问题描述】:

我想在我的 PCIe 设备上进行 I/O。我正在运行带有 linux 内核 4.4.0 的 Ubuntu 16.0.4 LTS

lspci -v 命令的输出是:

06:00.0 Unclassified device [00ff]: Device 1aa1:2000 (rev 01)
    Subsystem: Device 1aa1:2000
    Physical Slot: 1-4
    Flags: bus master, fast devsel, latency 0, IRQ 16
    Memory at f1008000 (32-bit, non-prefetchable) [size=8K]
    Memory at ee000000 (32-bit, non-prefetchable) [size=32M]
    Memory at f100a000 (32-bit, non-prefetchable) [size=4K]
    Memory at f0000000 (32-bit, non-prefetchable) [size=16M]
    Memory at f1000000 (32-bit, non-prefetchable) [size=32K]
    Capabilities: <access denied>
    Kernel driver in use: my_pci
    Kernel modules: my_pci

显然,PCI 地址是 32 位的。

我想知道如何使用 ioread32/iowrite32 函数读取/写入 BAR 地址。 unsigned char __iomem *mem 我的机器上的类型将是 64 位,如果我使用以下语句:

ioread32(mem + some_offset);

表达式 mem + some_offset 将是 64 位并导致崩溃。

我将如何进行 I/O?

【问题讨论】:

  • 条不能只写入,它们需要映射到虚拟内存。驱动程序通常在初始化之后执行它。您需要写入该地址 + 偏移量。
  • @stdcall 我知道,这就是在源代码中实现的方式。但我的问题略有不同——我的主机运行的是内核为 4.4.0 的 64 位 Ubuntu。查看我的lspci -v 输出,我们可以看到PCI 条地址是32 位的。所以我想知道/怀疑 ioread32 是 64 位地址的参数会导致未定义的行为。
  • 啊。知道了。给你一个答案。

标签: linux-kernel kernel linux-device-driver


【解决方案1】:

您使用的 PCI 设备使用 32 位寻址模式工作。 当您的 PC 枚举 BAR 并将物理地址写入 BAR 时。它写入一个掩码值,仅 64 位的低 32 位(在主机地址空间中) 在驱动程序上打印 OS/BIOS 分配给此 BAR 的物理地址并进行比较。

此外,这是一个物理地址,所以无论如何你都不能iowrite

所以我不太了解你的目标。

【讨论】:

  • 这正是我在打印地址时发现的。谢谢你的回答。
猜你喜欢
  • 1970-01-01
  • 2018-03-18
  • 2018-07-30
  • 2012-08-01
  • 2018-08-05
  • 2014-12-11
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
相关资源
最近更新 更多