我对 NIC(网络接口(interface)卡)MMIO 区域的使用感到困惑。
比如这是我电脑上某个网卡的信息
03:02.1 Ethernet controller: Intel Corporation 82546EB Gigabit Ethernet Controller (Copper) (rev 03)
Subsystem: Intel Corporation PRO/1000 MT Dual Port Server Adapter
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 64 (63750ns min), Cache Line Size: 64 bytes
Interrupt: pin B routed to IRQ 19
Region 0: Memory at e1b00000 (64-bit, non-prefetchable) [size=128K]
Region 2: Memory at e1a40000 (64-bit, non-prefetchable) [size=256K]
Region 4: I/O ports at 2000 [size=64]
Expansion ROM at e1a00000 [disabled] [size=256K]
Capabilities: <access denied>
Kernel driver in use: e1000
Kernel modules: e1000
我可以看到它有 2 个 MMIO 区域。
一开始我认为这2个区域是用来接收和发送数据包的,一个是RX缓冲区,另一个是TX缓冲区,但是经过一些测试,我认为我错了。
那么,这些 MMIO 区域实际上是用来做什么的?如果它们不是 TX 和 RX 缓冲区,那么这些缓冲区在哪里?
谢谢。
最佳答案
这些是内存基地址寄存器(BAR)。这是一个 OSDev explanation对于这个概念。内存 BAR 的使用取决于设备,并且可能是单独讨论的主题。例如,PCI 设备可能有一个小 BAR 来提供对其拥有的任何寄存器的访问。此外,设备 RAM 的某些部分可能会通过较大的 BAR 来暴露。
您的问题是关于 NIC 的,因此,实际上,您示例中的 BAR 之一是 NIC 寄存器所在的基本硬件地址。 e1000
驱动程序可以在 PCI 资源分配步骤中查询地址(说来话长,但是总而言之,合适的地址位于 的
)。并且,在其操作期间,hw_addr
field 中)结构 e1000_hwe1000
可以使用提到的地址+一些偏移量从某些寄存器读取或写入它们。您可以找到corresponding header中定义的不同寄存器的偏移量。 。例如,当驱动程序需要管理 Tx 环时,它可以使用正确的 registers 查询/更新其头部或尾部。 。例如,您可以看看驱动程序writes zeroes是如何进行的那里。
您还询问了 Rx 和 Tx 缓冲区位置。不太清楚您是否指的是数据缓冲区。如果是这样,恐怕 lspci 可能没有帮助,因为实际上数据包数据是使用主机内存缓冲区和 DMA 接收和传输的。 (直接内存访问)技术。例如,如果驱动程序想要传输数据包,它会获取存储数据包的缓冲区(主机内存)的物理地址,并通过 setting the packet buffer address 准备一个所谓的描述符。在里面。然后描述符被推送到设备。 NIC一旦获得描述符,就会发起DMA事务,即直接向主机内存发出内存访问请求,最终读入缓冲区的内容进行传输。
所以,我希望您发现我的简短回答至少有点有用。当然,您可以从驱动程序源代码和一些硬件相关文档中了解更多信息。
关于networking - NIC MMIO 区域有何用途?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40125512/