3. 中断控制器节点结构:标准骨架与核心属性

中断控制器节点是设备树中描述系统中断路由中枢的关键节点。无论是 ARM GIC、RISC-V PLIC 还是 x86 APIC,其节点结构都遵循一套标准骨架。本章将深入解析中断控制器节点的基本骨架、节点命名规范、地址映射以及 compatible 属性的配置方法。

3.1 标准中断控制器节点骨架

一个完整的中断控制器节点通常包含以下核心组成部分:节点名、单元地址(@address)、compatible 属性、interrupt-controller 标志、#interrupt-cells 以及 reg 属性。下面是一个典型的 ARM GICv2 中断控制器节点示例:

gic: interrupt-controller@f0001000 {
    compatible = "arm,cortex-a9-gic";
    interrupt-controller;
    #interrupt-cells = <3>;
    reg = <0xf0001000 0x1000>,
          <0xf0002000 0x0100>;
};
骨架要点:节点名通常使用通用名称(如 interrupt-controller),地址部分与 reg 中的第一个地址单元保持一致。interrupt-controller 是一个空属性,仅作为布尔标志存在。

3.2 节点名与地址配置

中断控制器节点的命名遵循设备树通用命名规范:<名称>@<单元地址>。其中:

  • 名称(node name): 通常使用 interrupt-controller 作为通用名称,便于操作系统自动识别。部分架构允许使用更具体的名称,如 gic、plic、ioapic。
  • 单元地址(unit address): 对应 reg 属性中第一个地址段(address cell)的值,使用十六进制表示。例如 @f0001000 表示该控制器映射在物理地址 0xf0001000。
  • 标签(label): 节点前可选的标签(如 gic:)用于在其他节点中通过 &gic 引用该中断控制器。
组件 示例 说明
标签 gic: 可选,用于 phandle 引用
节点名 interrupt-controller 通用名称,推荐使用
单元地址 @f0001000 与 reg 首地址一致
完整节点路径 interrupt-controller@f0001000 系统唯一标识
命名规范:虽然节点名可以自定义,但为了跨平台兼容性,强烈建议使用 interrupt-controller 作为名称。Linux 内核在初始化时会优先匹配该名称。
中断控制器节点骨架结构图 中断控制器节点骨架结构 interrupt-controller@f0001000 compatible interrupt-controller #interrupt-cells reg 属性提供物理地址映射,通常包含多个地址段(如 GICD 和 GICC) 节点名中的 @address 必须与 reg 的第一个地址单元匹配 reg = <0xf0001000 0x1000>

3.3 compatible 属性配置

compatible 属性是中断控制器节点与操作系统驱动匹配的关键。其配置遵循“具体到通用”的字符串列表原则:

compatible = "arm,cortex-a9-gic", "arm,gic";

上述配置表示该节点兼容 arm,cortex-a9-gic(具体型号)和 arm,gic(通用 GIC 接口)。操作系统在匹配驱动时,会按列表顺序依次尝试。

compatible 字符串 匹配优先级 适用场景
arm,cortex-a9-gic 高(优先匹配) 特定 Cortex-A9 平台优化驱动
arm,gic 低(回退匹配) 通用 GIC 驱动,兼容性更好
riscv,plic0 高 RISC-V PLIC 平台级中断控制器
ti,omap3-intc 高 TI OMAP3 专用中断控制器
配置陷阱:不要将 compatible 写成单个字符串(如 "arm,gic")而忽略具体型号。这会导致某些依赖具体硬件特性的驱动无法加载。始终将最具体的型号放在第一位。

3.4 中断控制器标志与 cells 配置

除了 compatible,中断控制器节点还必须包含两个关键属性:

  • interrupt-controller:空属性,声明该节点是一个中断控制器。没有此属性,系统不会将其识别为中断路由节点。
  • #interrupt-cells:指定中断描述符所需的 cell 数量。不同控制器类型取值不同:
    • ARM GIC:通常为 3(中断类型、中断号、触发方式与优先级)
    • RISC-V PLIC:通常为 1(仅中断号)
    • 简单中断控制器:通常为 2(中断号、触发方式)
// ARM GICv3 示例
gic: interrupt-controller@2f000000 {
    compatible = "arm,gic-v3";
    interrupt-controller;
    #interrupt-cells = <3>;
    reg = <0x2f000000 0x10000>,
          <0x2f100000 0x20000>,
          <0x2f200000 0x20000>;
};
compatible 属性匹配流程 compatible 属性驱动匹配流程 compatible = "a,b", "c,d" 步骤1:尝试匹配 "a,b"(具体型号) 匹配成功 → 加载专用驱动 匹配失败 → 尝试 "c,d" 匹配成功 → 加载通用驱动 列表顺序决定优先级:具体型号在前,通用接口在后

3.5 常见中断控制器 compatible 对照表

不同架构和厂商的中断控制器使用不同的 compatible 字符串。下表列出常见配置:

架构/厂商 中断控制器类型 compatible 字符串 #interrupt-cells
ARM GICv2 "arm,cortex-a9-gic" 3
ARM GICv3 "arm,gic-v3" 3
RISC-V PLIC "riscv,plic0" 1
TI OMAP INTC "ti,omap3-intc" 2
Xilinx Axi INTC "xlnx,xps-intc-1.00.a" 2
最佳实践:在编写中断控制器节点时,始终参考对应架构的 binding 文档。错误的 compatible 或 #interrupt-cells 会导致中断无法正确路由,系统可能无法响应外设中断。