NIC MMIO 区域用于什么?

What are NIC MMIO regions used for?

我对 NIC(网络接口卡)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个region是用来接收和发送数据包的,一个是RX buffer,一个是TX buffer,后来做了一些测试,我认为我错了。

那么,这些MMIO区域到底是用来做什么的呢?如果它们不是 TX 和 RX 缓冲区,这些缓冲区在哪里?

谢谢。

这些是内存基地址寄存器(BAR)。这是该概念的 OSDev explanation。 Memory BARs 的使用取决于设备,可能需要单独讨论。例如,一个 PCI 设备可能有一个小的 BAR 来提供对它拥有的任何 registers 的访问。此外,设备 RAM 的某些部分可能会通过较大的 BAR 暴露出来。

您的问题是关于 NIC 的,因此,实际上,您示例中的 BAR 之一是 NIC 寄存器所在的基本 HW 地址。 e1000 driver can query the address during PCI resource allocation step (这是一个长篇大论,但总而言之,一个合适的地址驻留在 hw_addr field of struct e1000_hw). And, during its operation, e1000 may read from some registers or write to them using the mentioned address + some offset. You can find offsets for different registers defined in the corresponding header. For instance, when the driver needs to manage, say, Tx ring, it may query/update its head or tail using the proper registers. For example, you may take a look at how the driver writes zeroes 那里。

您还询问了 Rx 和 Tx 缓冲区的位置。不太清楚你的意思是 data 缓冲区。如果是这样,恐怕 lspci 可能没有帮助,因为实际上数据包数据是使用主机内存缓冲区和其中的 DMA (direct memory access) technique. For instance, if the driver wants to transmit a packet, it obtains the physical address of the buffer where the packet is stored (host memory) and prepares a so-called descriptor by setting the packet buffer address 接收和传输的。然后将描述符推送到设备。网卡一拿到描述符,就会发起DMA事务,即直接向主机内存发出内存访问请求,最终会读入缓冲区的内容进行传输。

所以,我希望我的简短回答至少能对您有所帮助。当然,您可以从驱动程序源码和一些硬件相关文档中了解更多信息。