相关疑难解决方法(0)

内核空间中 PCI 内存的地址映射

我正在尝试从可加载的内核模块读取和写入 PCI 设备。

因此我关注了这篇文章

pci_enable_device(dev);
pci_request_regions(dev, "expdev");
bar1 = pci_iomap(dev, 1, 0);
// void iowrite32(u32 val, void __iomem *addr)
iowrite32( 0xaaaaaaaa, bar1 + 0x060000);  /* offset from device spec */
Run Code Online (Sandbox Code Playgroud)

但最终设备并没有按预期完成他的工作。然后我查看了后面的地址bar1,发现了一个非常大的值ffffbaaaaa004500

在这一点上,我真的不明白那里发生了什么,什么是对的。我可以解释bar1为内核地址空间内的地址,该地址直接0x60000指向与 PCI 芯片选择地址偏移的基地址吗?

我写的值怎么会bar1 + offset复制到设备上?iowrite32和后面的机制是如何工作的pci_iomap

感谢致敬

亚历克斯

PS:我成功测试了从同一地址的回读。


PCI设备的寄存器描述:

  • PCIBAR0PCI 基地址 0;用于内存映射配置寄存器
  • PCIBAR1PCI 基地址 1;用于 I/O 映射的配置寄存器
  • PCIBAR2PCI 基地址 2;用于本地地址空间 0
  • PCIBAR3PCI 基地址 3;用于本地地址空间 1
  • PCIBAR4 未使用的基地址
  • PCIBAR5 …

c kernel kernel-module linux-kernel pci

5
推荐指数
1
解决办法
8593
查看次数

实现PCIe Linux设备驱动程序(想从内核驱动程序访问我的卡寄存器)

我正在编写一个设备驱动程序来访问PCIe卡上FPGA中的内存.
卡片启动并被探测/发现: -

的/ proc/IOMEM

80000000-840fffff : PCI Bus #03
  80000000-83ffffff : 0000:03:00.0
  84000000-840fffff : 0000:03:00.0
Run Code Online (Sandbox Code Playgroud)

所以,读LDD /等我编写了一个调用request_mem_region80000000,并通过请求指向它的指针ioremap_nocache

1)我是否需要request_mem_region和a一样ioremap_nocache,我不能只使用后者?

/ proc/iomem insmod我的设备驱动程序后: -

80000000-840fffff : PCI Bus #03
  80000000-83ffffff : 0000:03:00.0
    80000000-8003ffff : fp2
  84000000-840fffff : 0000:03:00.0
Run Code Online (Sandbox Code Playgroud)

2)对我来说看起来不太合适......?

无论如何,读取不起作用(它没有编码如下,它有检查等): -

#define BAR_ADDR 0x80000000
void *base = ioremap_nocache(BAR_ADDR, 0x40000);
void *address = base + KNOWN_REG_LOCATION;
int data = ioread32(address);
printk("fp2: address:0x%08x, data:0x%08x\n", address, data);
Run Code Online (Sandbox Code Playgroud)

产出: -

address:0xfd500000, data:0xffffffff
Run Code Online (Sandbox Code Playgroud)

我可以 …

linux-kernel pci

4
推荐指数
1
解决办法
8012
查看次数

标签 统计

linux-kernel ×2

pci ×2

c ×1

kernel ×1

kernel-module ×1