2016-08-02 109 views
1

我想做的事我在我的PCIe device.I/O正在运行Ubuntu LTS 16.0.4与Linux内核4.4.0如何读取64位Linux内核环境的32位PCI条内存

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?

+1

酒吧只能写入,他们需要映射到虚拟内存。驱动程序通常在初始化之后进行。你需要写入该地址+偏移量。 – stdcall

+0

@stdcall我知道,这是如何在源代码中实现的东西。 但我的问题稍有不同 - 我的主机正在运行内核为4.4.0的64位Ubuntu。看看我的'lspci -v'输出,我们可以看到PCI条形地址是32位的。所以我怀疑/怀疑'ioread32'是64位地址的参数会导致未定义的行为。 – Monku

+0

啊。得到它了。给你一个答案。 – stdcall

回答

0

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

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

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

+0

这正是我在打印地址时发现的。感谢你的回答。 – Monku

+0

'lspci'将它们打印出来,如OP所示。 – 0andriy

相关问题