(为我之前的问题道歉,我的内核中的代码错误导致BAR的“所需映射空间”值错误,并且误导了我写了错误的问题描述。)
我正在为我自己的在 x86-64 PC 上工作的内核实现一个简单的 NVMe 驱动程序。由于我的英语很差,虽然我读过 PCIe 规范和其他资料,但我对这些事情不太确定:
在VMware上我定义了一个32GB的虚拟NVMe SSD,对应的值为:0xfea00004(BAR的初始值)0xffffc000(最低非零位为第14位,因此“空格”值为0x4000)
是否意味着SSD的寄存器已经映射到0xfea00000开始的地址,它需要的映射空间是16KB。 16KB对于这款SSD来说绝对够用吗?
顺便问一下,如果BAR的初始值是由固件或其他东西分配的,那么它们排列得很好,没有重叠吗?
鉴于您的问题有很多问题,我会以交错的方式回复:
- BAR 的初始值的含义是什么(由固件或其他方式为设备预先分配地址,或者只是随机的) 值)?
固件已对其进行设置,因此您无需进行枚举即可与设备通信。
- PCI 或 PCIe 硬件是否允许软件重新分配该地址?可以通过向BAR写入另一个值来更改映射地址吗?
是的,它可以更改,但是您需要确保其上游的网桥已设置为路由数据包。所有这些都是作为 PCIe 枚举过程的一部分完成的。操作系统通常会(再次)进行 PCIe 总线枚举并丢弃固件设置的旧值。
- 《PCI Express技术3.0》得出结论,不同标志位组合的BAR描述了3种地址空间:32bit 内存空间、64位内存空间和I/O空间。这是否意味着3 与设备通信的不同方式:32位mmio、64位mmio和 16位pio(使用x86输入/输出指令)?
有3个地址空间:
这是否意味着SSD的寄存器已映射到地址 0xfea00000,它需要的映射空间是16KB。绝对是16KB 这个SSD够用吗?
没错,对于这种情况,16KB 就足够了,最重要的结构(如命令队列和完成队列)位于 RAM 中,因此,它们不会消耗设备内存空间。
顺便说一句,如果 BAR 的初始值是由固件或 还有一些,它们排列得很好没有重叠吗?
是的,如果固件在将控制权传递给操作系统之前进行了 PCIe 枚举,您可以预期它做得正确并且没有重叠