1. 课程导论:ARM与RISC-V架构差异概述、驱动移植面临的挑战、设备树与中断控制器迁移的核心地位

1.1 ARM与RISC-V:两种指令集架构的基因差异

嵌入式系统驱动移植的本质,是从一种处理器架构的硬件抽象层迁移到另一种。ARM(v7-A/v8-A)与RISC-V(RV64GC)虽然都采用加载-存储(Load-Store)架构,但在特权级模型、中断控制器、系统寄存器访问方式上存在根本性差异。下表梳理了驱动移植中最关键的架构差异点:

对比维度 ARM (Cortex-A系列) RISC-V (RV64GC) 移植影响
特权级模型 EL0/EL1/EL2/EL3(4级) U/S/M(3级,可选HS) 中断入口/退出栈切换逻辑需重写
中断控制器 GICv2/v3(分发器+CPU接口) PLIC/CLINT(平台级+核级) 中断号映射、优先级、亲和性机制完全不同
系统寄存器访问 MRS/MSR 指令 + 协处理器 CSRRW/CSRRS 指令 上下文保存/恢复代码需逐条替换
设备树绑定 arm,gic-* 兼容字符串 riscv,plic0 / riscv,clint0 中断控制器节点必须重新描述
内存模型 强排序(Device-nGnRnE) 弱一致性(WMO + fence) DMA/MMIO 屏障指令需适配

核心认知:ARM 的 GIC 是架构强制的中断控制器,所有 Cortex-A 处理器必须实现 GIC 接口;而 RISC-V 的 PLIC/CLINT 是平台定义的,不同 SoC 可能使用不同的中断控制器实现。这意味着设备树中的 interrupt-controller 节点必须从 ARM 的 GIC 绑定完全迁移到 RISC-V 的 PLIC/CLINT 绑定。

1.2 驱动移植面临的三大挑战

从 ARM 到 RISC-V 的驱动移植不是简单的“查找替换”,而是涉及硬件抽象层重构、中断路径重映射和设备树重写的系统工程。以下是实践中最常见的三大挑战:

  1. 中断控制器语义不兼容:ARM GIC 使用 SPI(共享外设中断)和 PPI(私有外设中断)的编号体系,而 RISC-V PLIC 使用 context + source 的二维中断号。驱动中的 request_irq() 参数必须重新计算。
  2. 系统寄存器上下文保存/恢复:ARM 的 DAIF 中断掩码、SPSR_EL1 状态保存与 RISC-V 的 mstatus/sstatus 寄存器位域完全不同。中断嵌套、抢占逻辑需要从零实现。
  3. 设备树绑定与解析差异:ARM 设备树中 interrupt-parent = &gic; 配合 interrupts = <0 42 4>; 的三元组格式,在 RISC-V 中变为 interrupts-extended = <&plic0 1 42>; 的扩展格式。解析代码必须适配新的 of_irq_parse_one() 路径。

常见陷阱:许多开发者将 ARM 的 writel_relaxed() 直接替换为 RISC-V 的 writel(),忽略了 RISC-V 弱内存模型下 MMIO 操作需要显式插入 fence iorw, iorw 屏障。这会导致 DMA 描述符更新顺序错误,引发数据损坏。

1.3 设备树与中断控制器迁移的核心地位

在驱动移植的整个工作流中,设备树(Device Tree)和中断控制器(Interrupt Controller)的迁移占据了约 60% 的工作量。设备树是硬件拓扑的“唯一真相源”,而中断控制器是外设与 CPU 交互的“神经中枢”。两者必须协同迁移,否则驱动无法正确响应硬件事件。

下图展示了 ARM 与 RISC-V 在设备树中断路径上的核心差异:

ARM vs RISC-V 设备树中断路径对比 ARM 设备树中断路径 外设节点 (UART/GPIO) interrupt-parent = &gic; GIC 中断控制器节点 interrupts = <0 42 4>; // SPI CPU 接口 (GIC CPU IF) IRQ 号直接映射到异常向量 中断号:全局 SPI + 私有 PPI 亲和性:通过 GICD 寄存器组配置 RISC-V 设备树中断路径 外设节点 (UART/GPIO) interrupts-extended = <&plic0 1 42>; PLIC 平台级中断控制器 context + source 二维路由 CLINT 核级本地中断 MSI/MIE 寄存器 + 软件中断 中断号:全局 source + 本地 exception 亲和性:通过 PLIC context 映射到 hart

迁移要点:设备树迁移的核心工作包括:① 将 interrupt-parent 从 &gic 改为 &plic0;② 将 interrupts 三元组格式改为 interrupts-extended 扩展格式;③ 在 PLIC 节点中正确描述 riscv,ndev 属性和 interrupts-extended 到 CLINT 的映射。这些改动直接影响 irq_domain 的解析和中断号的最终分配。

1.4 中断控制器迁移的层次模型

中断控制器的迁移可以抽象为三个层次:设备树描述层、irq_chip 驱动层和中断分发层。每个层次在 ARM 和 RISC-V 之间都有对应的映射关系:

层次 ARM GICv2 RISC-V PLIC + CLINT 迁移动作
设备树描述 compatible = "arm,cortex-a15-gic" compatible = "riscv,plic0" 替换 compatible 字符串,重写 interrupt-cells
irq_chip 驱动 gic_handle_irq() → 读 GICC_IAR plic_handle_irq() → 读 PLIC_CLAIM 重写中断处理入口,替换寄存器访问指令
中断分发 GICD 分发器 → CPU 接口 → 核 PLIC 优先级仲裁 → context 选择 → CLINT 重新实现中断亲和性与负载均衡