有没有办法让Linux内核重新运行它的PCI初始化代码?
我正在寻找可以从驱动程序、用户区实用程序进行的内核模式调用,或者是一个系统调用,该系统调用将要求内核查看 PCI 总线并完全重新运行其初始化,或者初始化特定的设备。具体来说,我需要内核识别启动后添加到总线的设备,然后配置其地址空间、中断和其他配置参数,最后启用该设备,以便我可以为其加载驱动程序(除非这一切)作为驱动程序负载的一部分发生)。
为此,我一直使用 2.4.x 系列内核,目前正在使用 2.4.20,但如果重要的话,我会转向 2.4.37。该发行版是在 RAM 磁盘中运行的精简版 Red Hat 7.3,但我可以添加实现此功能所需的任何工具(只要它们能与 2.4 系列配合良好)。
如果一些背景知识有助于澄清我正在尝试做的事情:从冷启动,一旦进入 Linux,我就使用 GPIO 对 FPGA 进行编程。 FPGA 的一部分一旦编程,就会实现一个简单的 PCI 设备。目前,在对 FPGA 进行编程后,我重新启动系统,Linux 启动后会识别该设备并为其加载驱动程序。
不需要重新启动,我只想简单地要求内核在启动过程中执行任何操作来查找 PCI 设备(我将内核配置为自行查找 PCI 设备,而不是向 BIOS 询问该信息,这样 BIOS 就不需要知道这个设备(我希望))。
我相信 Linux 能够在编程后但重新启动之前看到设备,因为 scanpci
将在我编程后显示该设备,lspci -H 1
也会显示该设备。我只需要一种方法将其放入 /proc/pci
中,进行配置和启用。
I'm looking for either a kernel mode call that I can make from a driver, a userland utility, or a system call that will ask the Kernel to look at the PCI bus and either completely re-run its initialization, or initialize a specific device. Specifically, I need the Kernel to recognize a device that was added to the bus after boot and then configure its address space, interrupt, and other configuration parameters, and finally enable the device so that I can load the driver for it (unless this all happens as part of the driver load).
I'm stuck on the 2.4.x series Kernel for this, and am currently working with 2.4.20, but will be moving to 2.4.37 if it matters. The distro is a stripped down Red Hat 7.3 running in a ram disk, but I can add in whatever tools are needed to get this working (as long as they play nice with 2.4 series).
If some background would help clarify what I'm trying to do: From a cold boot, once in Linux I use GPIO to program an FPGA. Part of the FPGA, once programmed, implements a simple PCI device. Currently, after programming the FPGA, I reboot the system and Linux recognizes the device after coming up and loads the driver for it.
Instead of needing that reboot, I'd like to simply ask the Kernel to do whatever it does during boot up to find PCI devices (I have the Kernel configured to find PCI devices on its own, instead of asking the BIOS for that information, so the BIOS won't need to know about this device (I hope)).
I believe that Linux is capable of seeing the device after it is programmed but before a reboot, because scanpci
will show the device after I program it, as will lspci -H 1
. I just need a way to get it into /proc/pci
, configured and enabled.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
下面的命令将帮助用户重新扫描整个根集线器。
This below command will help the user to rescan it complete root hub.
如果您不知道如何重做 PCI 扫描,您可以使用 kexec 加快重新启动速度。如果您还没有的话,您可以在 LKML 上询问这个问题。
卸载/重新加载模块没有帮助,不是吗?
You could speed up the reboot with kexec, if you don't figure out how to get the PCI scan redone. You could ask this on the LKML, if you haven't already.
unloading/reloading the module doesn't help, does it?
http://www.linuxjournal.com/article/5633 建议您应该能够执行以下操作它与使用
pcihpfs
的 2.4 内核一起使用。如果这不起作用,也许驱动程序不支持热插拔?
http://www.linuxjournal.com/article/5633 suggests you should be able to do it with 2.4 kernels using
pcihpfs
.If that isn't working, maybe the driver doesn't support hotplug?
如果您在使用其他 PCI 设备时重新配置它们的地址,则可能会导致系统崩溃。
更好的方法是仅配置新卡。如果您的内核支持 Cardus 设备,它已经知道如何配置新插入的 PCI 设备(这就是 Cardbus)。您只需要弄清楚如何让内核执行此操作...
内核模块应该可以执行此操作。即使您无法获得内置热插拔代码,您也应该能够通过调用
pci_bus_write_config_dword()
等来设置 pci 资源。可能还需要进行一些 IRQ 路由设置。It would probably crash the system if you reconfigured the addresses of other PCI devices while they are in use.
A better way would be to just configure the new card. If your kernel has support for Cardus devices, it already knows how to configure a newly-inserted PCI device (which is what Cardbus is). You just need to figure out how to get the kernel to do it...
It should be possible for a kernel module to do this. Even if you can't get built-in hotplug code, you should be able to set the pci resources using calls to
pci_bus_write_config_dword()
and friends. There is probably some IRQ routing setup to do as well.