Linux内核网络驱动设备树解析与中断绑定实战 - 第1节

1.1 Linux 内核网络驱动概述

Linux 内核网络驱动是操作系统与物理网络设备之间的桥梁,负责数据包的收发、链路状态管理以及硬件控制。理解网络驱动的整体架构,是后续解析设备树与中断绑定的基础。

1.1.1 网络驱动在协议栈中的位置

Linux 网络协议栈自顶向下分为:系统调用接口 → 套接字层 → 传输层(TCP/UDP) → 网络层(IP) → 数据链路层 → 网络设备驱动 → 物理硬件。网络驱动位于数据链路层与物理硬件之间,直接操作硬件寄存器、描述符环和中断控制器。

关键认知: 网络驱动不处理 TCP 重传或 IP 路由,它的核心职责是:
(1) 初始化硬件并注册 net_device 结构体;
(2) 实现 open/stop/start_xmit 等操作函数;
(3) 处理硬件中断并上送数据包到协议栈。

1.1.2 网络驱动的核心数据结构

数据结构 所在文件 核心作用
struct net_device include/linux/netdevice.h 网络设备的抽象,包含设备名、MAC 地址、操作函数集、统计信息等
struct net_device_ops include/linux/netdevice.h 驱动必须实现的回调函数:ndo_open、ndo_stop、ndo_start_xmit 等
struct sk_buff include/linux/skbuff.h 套接字缓冲区,承载网络数据包在内核各层之间传递
struct napi_struct include/linux/netdevice.h NAPI 轮询机制的核心结构,用于减少中断频率、提升吞吐

1.1.3 网络驱动的注册与生命周期

  1. 模块加载:调用 platform_driver_register() 或 pci_register_driver() 注册驱动。
  2. 探测阶段:probe 函数被调用,解析设备树获取资源,分配 net_device,设置操作函数,注册网络设备。
  3. 打开设备:用户执行 ifconfig eth0 up 触发 ndo_open,申请 DMA 缓冲区、注册中断、启动 NAPI。
  4. 数据收发:ndo_start_xmit 发送数据包;硬件中断或 NAPI 轮询接收数据包。
  5. 关闭设备:ndo_stop 停止队列、释放中断、回收缓冲区。
  6. 模块卸载:remove 函数释放所有资源,注销网络设备。
网络驱动生命周期流程图 模块加载 / probe ndo_open 打开设备 数据发送 (start_xmit) 数据接收 (中断/NAPI) ndo_stop 关闭设备

1.2 设备树(DT)在驱动中的作用

设备树是一种描述硬件资源的数据结构,以树状节点形式向内核传递:寄存器地址、中断号、时钟频率、GPIO 引脚、DMA 通道等平台信息。在 ARM/ARM64/RISC-V 等非 x86 架构中,设备树是驱动获取硬件配置的主要途径。

1.2.1 设备树的核心语法

/dts-v1/;

/ {
    model = "Embedded Network Board";
    compatible = "vendor,board-version";

    soc {
        #address-cells = <1>;
        #size-cells = <1>;

        eth0: ethernet@10000000 {
            compatible = "vendor,eth-driver";
            reg = <0x10000000 0x1000>;
            interrupts = <0 33 4>;
            interrupt-parent = <&gic>;
            phy-mode = "rgmii";
            local-mac-address = [00 11 22 33 44 55];
        };
    };
};
属性 含义 驱动中对应 API
compatible 驱动匹配字符串,用于 of_match_table 匹配 of_match_node()
reg 寄存器基地址与长度 platform_get_resource()
interrupts 中断号、触发类型(高电平、上升沿等) platform_get_irq()
interrupt-parent 中断控制器 phandle irq_of_parse_and_map()
phy-mode PHY 接口模式(MII/RMII/RGMII) of_get_phy_mode()

1.2.2 设备树与驱动绑定的流程

  1. 内核启动时解析 DTB(设备树二进制),构建 device_node 树。
  2. 总线驱动(如 platform bus)扫描设备树节点,创建 platform_device。
  3. 驱动注册时,内核将 of_match_table 中的 compatible 与设备树节点匹配。
  4. 匹配成功后调用驱动的 probe 函数,传入 platform_device 指针。
  5. probe 函数通过 device_node 读取 reg、interrupts 等属性,完成硬件初始化。
实战要点: 在编写网络驱动时,务必在 of_match_table 中声明与设备树一致的 compatible 字符串。常见错误是 compatible 拼写不一致导致 probe 不被调用。
设备树与驱动绑定流程 DTB 解析 创建 device_node platform_device 注册 compatible 匹配 probe 函数执行

1.3 中断子系统基础概念

中断是硬件通知 CPU 有事件需要处理的机制。在网络驱动中,中断用于通知数据包到达、发送完成、链路状态变化等事件。Linux 中断子系统由 中断控制器、中断描述符、中断处理程序 和 下半部机制 组成。

1.3.1 中断类型与触发方式

类型 触发方式 设备树中编码 典型场景
电平触发 高电平 / 低电平 IRQ_TYPE_LEVEL_HIGH (4) / IRQ_TYPE_LEVEL_LOW (8) 共享中断、边沿敏感设备
边沿触发 上升沿 / 下降沿 IRQ_TYPE_EDGE_RISING (1) / IRQ_TYPE_EDGE_FALLING (2) 网络控制器中断、GPIO 按键
快速中断 不可屏蔽 IRQ_TYPE_NONE (0) 时钟中断、紧急事件

1.3.2 中断处理流程

  1. 硬件触发:外设拉高/拉低中断线,中断控制器向 CPU 发送 IRQ。
  2. CPU 响应:CPU 保存上下文,跳转到中断向量表,执行通用中断入口。
  3. 中断分发:内核根据中断号查找 irq_desc,调用注册的 handle_irq 函数。
  4. 上半部执行:在中断上下文中执行快速处理(如清除中断标志、调度 NAPI)。
  5. 下半部执行:通过 tasklet、workqueue 或 NAPI 轮询在软中断上下文中完成数据包处理。
中断上下文限制: 上半部中不能调用可能导致睡眠的函数(如 kmalloc(GFP_KERNEL)、mutex_lock)。网络驱动通常在上半部仅做最小处理,将数据包接收放到 NAPI 轮询中完成。

1.3.3 设备树中的中断绑定

设备树通过 interrupts 属性和 interrupt-parent 属性描述中断连接关系。中断控制器节点需要提供 #interrupt-cells 指定中断描述符的单元数。

// 中断控制器节点(GIC)
gic: interrupt-controller@10400000 {
    compatible = "arm,cortex-a15-gic";
    #interrupt-cells = <3>;
    interrupt-controller;
    reg = <0x10400000 0x10000>;
};

// 网络设备节点引用 GIC
ethernet@10000000 {
    compatible = "vendor,eth-driver";
    reg = <0x10000000 0x1000>;
    interrupt-parent = <&gic>;
    interrupts = <0 33 4>;  // 类型=SPI, 中断号=33, 触发=高电平
};

其中 interrupts = <0 33 4> 的含义:

  • 第一个单元:中断类型(0=SPI 共享外设中断,1=PPI 私有外设中断)。
  • 第二个单元:中断号(相对于中断控制器的偏移)。
  • 第三个单元:触发标志(4=高电平触发)。
中断子系统架构与设备树绑定关系 网络控制器 interrupts = <0 33 4> GIC 中断控制器 #interrupt-cells = <3> CPU 核心 中断向量表 NAPI / tasklet 软中断上下文 设备树描述硬件连接 驱动解析中断资源

1.4 本章知识结构总结

知识模块 核心内容 与后续章节的关联
网络驱动概述 net_device、net_device_ops、sk_buff、NAPI 第 3 章实现具体驱动操作函数
设备树基础 compatible、reg、interrupts、of_match_table 第 4 章解析设备树获取 MAC/PHY 参数
中断子系统 中断类型、触发方式、上半部/下半部、设备树中断绑定 第 5 章注册中断与 NAPI 集成
学习路径提示: 本章是后续所有实战章节的基石。建议读者在开发板上实际导出设备树文件(dtc -I fs -O dts /sys/firmware/devicetree/base),对照本节内容逐字段分析网络节点,加深理解。