基地址寄存器如何获取地址?

我已经完成了在linux下的FPGA开发FPGA的pcie驱动程序。 一切工作正常。 但是我想知道FPGA的PCI端点的基地址寄存器在哪里得到基地址。 当我生成PCIe端点时,我可以设置BAR的长度,但不是更多。

在PCIe驱动程序中,我执行像pci_enable_device这样的标准function,但是我没有专门设置基地址。

那么操作系统在启动过程中是否设置了基地址? 或者它是如何工作的? 就我而言,我想知道如果一个pcie设备连接,操作系统一般会做什么初始化。 因为我确实在卸载驱动程序的时候在lspci中看到了我的pci设备。

亲爱的托马斯

PCI设备的地址分配通常在BIOS级完成。 让我们引用x86平台。 如果仔细看看系统地址图,就会是这样(图片来自Darmawan Salihun的BIOS DISASSEMBLY NINJUTSU)

在这里输入图像描述

在地址映射上,有一个专用空间来映射PCI内存区域。 使用/proc/iomem的输出可以复制相同的结果。

这个实现是依赖于平台的,而且当BIOS“知道”这个平台的时候,它将把专用于PCI插槽的地址放在一边。 当设备插入插槽时,BIOS与设备上的固件进行交互并实际设置设备的存储区域,以使得操作系统可以使用它。

现在来到司机部分。 在Linux中,驱动程序遵循构成核心层(PCI核心),主控制器驱动程序(PCI控制器/主设备)和客户端驱动程序(PCI设备)的称为“Linux设备模型”的特定标准。 当PCI设备(客户端)插入插槽时,相应的主控制器知道附件,并进一步通知PCI核心,从而出现在lspci的输出中。

lspci显示由主机控制器识别的设备,在这种情况下,它可能与驱动程序绑定,也可能不绑定。 核心进一步遍历系统中的驱动程序,找到匹配的驱动程序,并附加到该设备。

所以,你在lspci的输出中看到这个设备的原因是因为主控制器已经识别了设备,并且已经通知了PCI核心。 即使有任何驱动程序连接到设备也没关系。

在大多数消费级计算机上,BAR分配似乎在BIOS中完成。

我想,在支持热插拔的体系结构中,这必须完成或至少由操作系统触发。