【问题标题】:How does base address register gets address?基地址寄存器如何获取地址?
【发布时间】:2014-06-05 13:11:18
【问题描述】:
我已经完成了在 linux 发行版下为 FPGA 开发的 pcie 驱动程序。一切正常。但我想知道 FPGA 的 PCI 端点中的基地址寄存器在哪里获得基地址。当我生成 PCIe 端点时,我能够设置 BAR 的长度,但不能设置更多。
在 PCIe 驱动程序中,我执行 pci_enable_device 之类的标准功能,但我没有专门设置基地址。
那么操作系统在启动时会设置基地址吗?或者它是如何工作的?
顺便说一句,我想知道如果连接了 pcie pcie 设备,操作系统通常会做什么初始化。因为即使驱动程序已卸载,我也确实在 lspci 中看到了我的 pci 设备。
亲切的问候
托马斯
【问题讨论】:
标签:
linux
enumeration
pci
addressing
base-address
【解决方案1】:
PCI 设备的地址分配通常在 BIOS 级别完成。让我们参考x86平台。如果我们仔细查看系统地址映射,它会是这样的(图片来自 BIOS DISASSEMBLY NINJUTSU,Darmawan Salihun)
在地址映射上,有一个专用空间来映射 PCI 内存区域。可以使用/proc/iomem 的输出复制相同的内容。
此实现取决于平台,并且由于 BIOS“了解”平台,它会留出专用于 PCI 插槽的地址。当设备插入插槽时,BIOS 会与设备上的固件交互,并实际为设备设置内存区域,以便操作系统可以使用它。
现在进入驱动程序部分。在 Linux 中,驱动程序遵循称为“Linux 设备模型”的特定标准,该标准由核心层(PCI 核心)、主机控制器驱动程序(PCI Controller/Masters)和客户端驱动程序(PCI 设备)组成。当 PCI 设备(客户端)插入插槽时,相应的主机控制器知道该附件,并进一步通知 PCI 核心,因此出现在lspci 的输出中。
lspci 显示由主机控制器识别的设备,在这种情况下,它可能会或可能不会绑定到驱动程序。内核进一步遍历系统中的驱动程序,找到匹配的驱动程序,并附加到该设备。
所以,您在lspci 的输出中看到该设备的原因是主机控制器已识别该设备,并已通知 PCI 核心。即使设备上是否连接了任何驱动程序也没关系。
【解决方案2】:
在大多数消费级计算机上,BAR 分配似乎是在 BIOS 中完成的。
我认为在支持热插拔的架构中,这必须由操作系统完成或至少由操作系统触发。