我对 Linux on x86 上的 PCIe 子系统的详细工作原理存有疑问。
据我所知,要仅使用 mmio 与 PCIe 设备通信,需要执行以下操作:
我读到这是在总线枚举中完成的? 目前有一种称为 ECAM 的东西,为所有 BDF 保留 256MB。 那么我将无法将配置空间映射到任意物理地址?
启动时这是由固件完成的?那么这个厂商(主板)有依赖性吗? 如果我想更改此映射或热插拔怎么办,如何分配 phy 地址? 它在 x86 上如何工作? 我需要确保新的物理地址不会与已分配的物理地址冲突?
我知道如何编写 pcie 驱动程序,但由于某种原因很难找到这些底层细节,尤其是关于如何设置 PCIe 和 mmio 映射的英特尔文档。
PCIe配置空间出现在固定的MMIO地址处。这是由硬件或 BIOS 控制的,并且该地址不能由软件更改。软件通过读取名为“MCFG”的 ACPI 表来发现地址。当然软件可以将其映射到任意虚拟地址。
设备 BAR 也由 BIOS 配置。它们可以通过软件更改,但有一些限制,因此通常软件只是将 BAR 设置为 BIOS 设置的值。软件可以直接读取 BAR 来发现地址。同样,这些物理地址需要映射到虚拟地址空间才能被访问。
热插拔时,系统软件不需要分配BAR值。是的,执行此操作的软件确实需要识别合适的内存范围和 oid 冲突。