1. Linux网络设备驱动概述
网络设备驱动是Linux内核中负责管理物理或虚拟网络接口的核心组件。作为一名从事嵌入式系统开发多年的工程师,我处理过从百兆以太网卡到5G模块的各种网络设备驱动开发。网络驱动的工作机制直接影响着整个系统的网络吞吐量、延迟和稳定性。
在Linux内核中,每个网络接口都对应一个net_device结构体实例。这个数据结构就像网络设备的"身份证",包含了设备名称、MAC地址、MTU等关键属性,以及一组操作函数指针。当我们在用户空间执行ifconfig命令时,显示的信息大多就来自这个结构体。
注意:在Linux 3.0之后的内核版本中,网络设备驱动的注册方式有所变化,推荐使用alloc_netdev_mqs()替代旧的alloc_netdev()函数,以更好地支持多队列网卡。
2. 网络设备驱动核心架构
2.1 net_device结构体解析
struct net_device是网络驱动的核心数据结构,其重要字段包括:
c复制struct net_device {
char name[IFNAMSIZ]; // 设备名,如eth0
unsigned long mem_end; // 共享内存结束地址
unsigned long mem_start; // 共享内存起始地址
unsigned long base_addr; // I/O基地址
unsigned int irq; // 中断号
unsigned char if_port; // 物理端口类型
unsigned char dma; // DMA通道
unsigned long state; // 设备状态标志
struct net_device_stats stats; // 网络统计信息
const struct net_device_ops *netdev_ops; // 设备操作集
// ... 其他字段
};
在实际开发中,我们通常会为特定硬件扩展这个结构体,添加私有数据:
c复制struct my_netdev_priv {
spinlock_t lock;
struct sk_buff_head rx_queue;
dma_addr_t dma_handle;
// 硬件特定寄存器映射等
};
2.2 操作函数集net_device_ops
net_device_ops结构体定义了驱动必须实现的操作方法:
c复制struct net_device_ops {
int (*ndo_init)(struct net_device *dev);
void (*ndo_uninit)(struct net_device *dev);
int (*ndo_open)(struct net_device *dev);
int (*ndo_stop)(struct net_device *dev);
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb,
struct net_device *dev);
void (*ndo_set_rx_mode)(struct net_device *dev);
// ... 约30个操作函数
};
其中最关键的是ndo_start_xm
