Linux 内核游记 (2)

本文深入探讨Linux内核中Intel 8255x 10/100 Mbps网卡的驱动程序,涉及PCI接口、CSR(Control/Status Registers)、DMA机制以及中断处理。文章详细解释了如何通过CSR进行设备控制,如何利用DMA提高数据传输效率,并介绍了中断处理和NAPI(Non-Blocking Adaptive Interrupt Processing)在提高网络性能中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网络设备驱动

上一篇分析的loopback是所谓的"伪设备",即它不对应真实世界中的硬件,而只是一种软件抽象。今天我们来看一个真实硬件设备的驱动程序,它就是Intel 8255x 10/100 Mbps网卡,对应的内核文件是drivers/net/ethernet/intel/e100.c

e100

8255x是一系列网卡的统称,包括82557, 82558, 82559, 82550,82551。以82557为例,其硬件模块图如下所示
82557硬件模块图
可以看到,该型网卡主要由三部分组成:

  • MAC, 即图中标有82557的部分,是核心部件
  • PHY, 即物理层接口设备,与核心部件之间以 MII 连接
  • EEPROM, 用来存储相关节点地址和 PCI 配置参数等信息

PCI接口

来到代码的最末,可以看到模块的初始化函数中只是简单的进行了PCI驱动信息的注册。
pci_driver结构中,最重要的两个成员分别是id_tableprobe。前者列出了设备支持的PCI标识信息,后者为当系统发现有匹配的PCI设备插入时所调用的函数。
id_table中包含以下成员:vendor, device, subvendor, subdevice, class, class_mask, driver_data。对于Intel的这款网卡来说,vendor0x8086表示Intel,class0x0200表示以太网设备。代码中定义了宏

#define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\
	PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \
	PCI_CLASS_NETWORK_ETHERNET << 8, 0xFFFF00, ich }

来辅助id_table信息的填充。从代码可以看到,在这个表里注册的设备可真多呀1。可不要忘了使用MODULE_DEVICE_TABLE()导出我们的设备列表。

probe函数中,除了之前说过的对net_device结构的填充之外,还要进行PCI相关的初始化操作,关于这部分,可参考内核文档2。主要的API包括:

  • pci_enable_device() / pci_disable_device()
  • pci_request_regions() / pci_release_region()
  • pci_set_dma_mask()
  • pci_iomap() / pci_iounmap()

说到pci_iomap(),就不得不提及PCI配置空间。每个PCI设备都至少有256字节的地址空间,其中前64字节是标准化的,我们现在就来看一下这块网卡的配置空间的情况。
PCI配置空间
为什么说pci_iomap()跟这个配置空间有关呢。注意图中用红框框起来的部分,那就是所谓的基地址,共有6个,官方名称为PCI_BASE_ADDREESS_0PCI_BASE_ADDREESS_5。而

extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值