如何强制Linux内核枚举PCI-E总线?

Linux内核2.6

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

我如何强制重新枚举Linux中的pci-e总线? 有一个简单的命令,或者我将不得不做内核更改? 我需要能够热插拔pcie设备。

Solutions Collecting From Web of "如何强制Linux内核枚举PCI-E总线?"

我想知道你是在哪个平台上工作的:在x86系统上工作的一个工作(也就是hack)是让BIOS基本上静态配置一个PCI设备,在任何总线,设备,FPGA正常工作的地方,然后OS会枚举设备并为其保留PCI空间(即使设备不在那里)。 然后在你的设备驱动程序中,你将不得不做一些额外的事情,比如在fpga编程之后手动设置BAR和int行。 当然,这需要修改BIOS,如果您正在与BIOS供应商合作,您可以与他们签订合同,以便为您进行此更改,如果您没有与BIOS供应商合作,那么这将变得更加困难。我在x86上的VxWorks上工作,我们有一个AMI为我们的主板做一个自定义的BIOS …

如果您没有BIOS,请考虑在引导加载程序中对其进行编程,您已经有能力从磁盘读取数据,并且添加GPIO功能可能不会太困难(假设您使用的是jtag和GPIO?),事实取决于你使用的bootloader可能已经能够做GPIO了?

修改内核的问题是,你必须在PCI枚举之前找到可以读取位文件的最佳位置。例如,如果在PCI之后磁盘设备驱动程序被初始化,那么显然你必须做一些彻底改变内核只是为了读取PCI枚举之前的位文件,这可能会导致其他恼人的问题…

另外一个你可能已经发现的选项,开发时间确实没问题:打开系统电源,编程fpga板,然后重新设置(没有重新启动,例如:sudo reboot),FPGA应该保持它的配置,和Linux应枚举它…

以root身份,请尝试以下命令:

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

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

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

在所涉及的卡未被BIOS分配任何资源的情况下,我必须这样做,因为所请求的区域需要64位地址,并且BIOS仅以32位地址分配来操作。 我能够事后进去,将这些地址(最初由BIOS分配)更改为我认为合适的任何地址,插入内核模块,然后我的驱动程序会映射并使用这些新分配的地址了解其中的差异。

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

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