【问题标题】:How can the linux kernel be forced to enumerate the PCI-e bus?linux内核如何强制枚举PCI-e总线?
【发布时间】:2012-09-06 23:58:50
【问题描述】:

Linux 内核 2.6

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

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

【问题讨论】:

  • 设备驱动程序不应该解决这个问题吗?
  • 不,似乎 pci-e 驱动程序仅在启动时自动枚举,如果在启动后插入设备,则没有任何反应。 lspci 显示没有设备并且没有设备文件存在
  • 我认为答案是“不”,尽管我很愿意犯错。 Altera 似乎有一种解决方法,谷歌搜索“Altera FPGA Configuration via Protocol”。如果我对这篇论文的理解正确,Altera 在(一些?)Stratix V 器件中提供了一个闪存,它始终可用于 PCIe 总线枚举,而大部分 FPGA 可以在闲暇时(重新)编程。

标签: linux configure fpga pci-e


【解决方案1】:

以 root 身份尝试以下命令:

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

查看此链接了解更多信息:http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci

【讨论】:

  • 是的,我在尝试解决这个问题的谷歌冒险中看到了这一点。它不起作用,即使我在 linux 构建中启用了 CONFIG_HOTPLUG。
  • 这似乎是一个简单的解决方案,但我可以想象,如果这会导致 PCI 总线脱机一秒钟左右,它可能会导致您的 PCI 设备/驱动程序崩溃......
  • 如果你需要sudo,你会得到“permission denied”。在这种情况下,请使用sudo sh -c "echo 1 > /sys/bus/pci/rescan"
  • 轻松:回声 1 | sudo tee /sys/bus/pci/rescan
  • 在重新扫描之前,通过将 1 写入 /sys/bus/pci/devices/.../remove 来删除卡的 linux-knowledge。
【解决方案2】:

我想知道你在什么平台上:在 x86 系统上工作的解决方法(又名 hack)是让 BIOS 基本上静态地在 FPGA 通常登陆的任何总线、设备、功能上配置 PCI 设备,然后操作系统将枚举设备并为其保留 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应该枚举它......

【讨论】:

  • 重启循环是我们目前正在做的事情。它是一个 Marvell ARM 平台,用作 Altera Arria II fpga 的控制器板。
  • 我还认为可以修改内核,使其在枚举之前加载 fpga。我不确定这是否可行/可能。
  • 关于引导加载程序模块的另一件事:如果您的引导加载程序不可现场升级,请确保在发布之前考虑向其添加复杂功能的后果......或者考虑制作它的方法现场可升级。
【解决方案3】:

打开计算机后,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 线的能力,这种方法就应该有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-02
    • 2013-01-15
    • 1970-01-01
    • 2014-11-23
    • 2015-05-31
    • 1970-01-01
    • 2014-05-30
    • 2012-09-16
    相关资源
    最近更新 更多