2016-08-02 112 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

相關問題