如何强制linux内核枚举PCI-e总线?

时间:2012-09-13 20:08:50

标签: linux configure fpga pci-e

Linux内核2.6

我有一个加载到GPIO上的fpga连接到运行linux的开发板。 fpga将通过pci-express总线传输和接收数据。但是,这是列举的 在启动时,因此没有发现链接(因为启动时没有加载fpga)。

如何在linux中强制重新枚举pci-e总线? 有一个简单的命令还是我必须进行内核更改? 我需要能够热插拔pcie设备。

3 个答案:

答案 0 :(得分:25)

以root用户身份,尝试以下命令:

echo "1" > /sys/bus/pci/rescan

有关详细信息,请参阅此链接:http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci

答案 1 :(得分:10)

我想知道你所使用的平台:在x86系统上运行的解决方案(也称为hack)是让BIOS基本上静态配置PCI设备,无论FPGA通常驻留在哪个总线,设备和功能上,然后操作系统将枚举设备并为其保留PCI空间(即使设备不在那里)。然后在你的设备驱动程序中,你必须做一些额外的事情,比如在fpga编程后手动设置BAR和int线。当然这需要修改BIOS,如果您正在与BIOS供应商合作,您可以与他们签订合同以便为您进行此更改,如果您不与BIOS供应商合作则会更加困难...还要记住我正在x86上使用VxWorks,我们有一个AMI为我们的主板制作自定义BIOS ...

如果您没有BIOS,那么考虑在引导加载程序中对其进行编程,您已经能够从磁盘读取,并且添加GPIO功能可能并不太难(假设您使用的是jtag和GPIO? ),实际上根据您使用的引导加载程序,它可能已经能够进行GPIO了吗?

修改内核来执行此操作的问题是,您必须在PCI枚举之前找到可以读取位文件的最佳位置...例如,如果在PCI之后初始化磁盘设备驱动程序,那么显然您必须对内核进行一些根本性的更改才能在PCI枚举之前读取位文件,这可能会导致其他烦人的问题...

您可能已经发现的另一个选项,它实际上只适用于开发时间:启动系统,编程fpga板,然后执行重置(无需重启,例如:sudo reboot now), FPGA应该保持其配置,linux应该枚举它......

答案 2 :(得分:6)

打开计算机后,BIOS会枚举PCI总线并尝试满足所有IO空间和内存映射IO(MMIO)请求。它最初设置这些BAR,当操作系统加载这些BAR时,操作系统可以根据需要更改这些BAR,而PCI总线驱动程序再次枚举总线。在BIOS已经尝试配置它们并且操作系统已经加载之后,系统的超级用户甚至可以运行命令setpci来更改这些BAR(可能导致驱动程序失败以及其他一些不好的事情,如果完成的话)不适当)。

如果有问题的卡未被BIOS分配任何资源,我必须执行此操作,因为请求的区域需要64位地址且BIOS仅使用32位操作地址分配。事后我能够进入事实并将这些地址(最初由BIOS分配)更改为我认为合适的地址,插入内核模块,我的驱动程序将映射并使用这些新分配的地址知道差异。

热插拔PCI-Express卡存在的问题是,如果主板/背板上不需要特定的热插拔控制器,则无法打开/关闭插槽的电源。没有这些热插拔控制器来关闭插槽的电源可能会导致插入和/或移除卡时微小插针之间的短路,如果电源仍然存在。但是,热插拔事件可以由任一端(主机端点设备)启动。这似乎并非如此,但是如果您的FPGA已经与根联合体建立了链接,则问题的可能解决方案是生成热插拔中断以在操作系统中重新扫描总线。

但是存在一个主要问题 - 如果您的卡实际上没有获得到根联合体的链接,它将无法生成任何热插拔事件;这似乎是这种情况。启动后,FPGA应切换PCIe总线上的 PRESENT 线,告诉操作系统有一个可以枚举的卡。一旦检测到,操作系统应尝试建立到卡的链接并将内存区域分配给设备。操作系统枚举卡后,您将能够加载驱动程序,并在lspci中查看。您声明您正在使用内核2.6,它支持热插拔和动态资源分配,因此只要您的FPGA支持切换PRESENT PCIe线路,此方法也可以正常工作。