1. PolarFire SoC平台概览与课程目标
PolarFire SoC 是 Microchip 推出的一类将 RISC-V 硬核处理器子系统与 FPGA 可编程逻辑 fabric 集成在同一芯片上的异构计算平台。理解它的第一步,是把它与两类常见器件区分开:一类是纯 FPGA,逻辑可编程但缺少完整的应用处理器;另一类是通用应用处理器 SoC,CPU 性能强但外设接口固定、难以按需扩展。PolarFire SoC 的价值恰在于把两者放进同一颗芯片,让 Linux 运行在确定性的 RISC-V 硬核上,同时让 FPGA fabric 承担自定义外设、实时通路和高速接口。
从架构上看,PolarFire SoC 的处理器子系统(MSS)包含一个 64 位 RV64GC 应用核心复合体(通常为四核 U54,支持 Linux 与 MMU)以及一个 64 位 RV64IMAC 实时核心(E51,无 MMU,适合裸机或实时任务)。U54 集群共享 L2 缓存,通过总线矩阵连接 DDR 控制器、eNVM、外设和 FPGA fabric。E51 则更适合承担启动引导、实时控制或安全监控。这种“应用核 + 实时核”的组合,使同一芯片既能跑 Linux 用户态程序,又能保留低延迟响应能力。
异构集成的关键在于 fabric 与 MSS 之间的接口。FPGA fabric 中的自定义逻辑可以通过 AXI 或 AHB 总线映射到处理器的地址空间,Linux 侧以平台设备或字符设备的形式访问;反过来,处理器也可以通过 fabric 中的 DMA 或中断控制器与逻辑交互。这意味着一个典型设计里,Linux 负责管理文件系统、网络协议栈和上层应用,而 fabric 负责采集、时序敏感的信号处理或专用加速。两者通过设备树描述连接关系,通过驱动完成数据交换。
嵌入式 Linux 在这个平台中扮演“资源管理者与抽象层”的角色。它把 DDR、eNVM、外设控制器和 fabric 映射的寄存器统一纳入虚拟内存管理,让应用程序无需关心物理地址;它通过设备树把硬件拓扑翻译成内核可识别的设备节点;它用驱动把 fabric 中的自定义逻辑包装成标准接口,例如把一段采集逻辑变成 /dev/pf_sensor0 字符设备。没有 Linux,fabric 与处理器的协作需要大量裸机代码;有了 Linux,开发者可以复用网络、文件系统和进程调度能力,把精力集中在业务逻辑与硬件加速上。
本课程围绕“构建一个可启动、可扩展、可调试的 PolarFire SoC Linux 平台”展开,主线包括六个方面。第一,启动链:从 eNVM 中的 HSS(Hart Software Services)到 U-Boot,再到 Linux 内核,理解每一级如何加载下一级、如何传递设备树和启动参数。第二,设备树:掌握 DTS 语法、节点与属性含义,能够为 fabric 中的自定义 IP 编写正确的地址映射和中断描述。第三,外设驱动:从平台设备驱动模型出发,实现字符设备、GPIO、I2C/SPI 等常见接口,并理解 fabric 自定义外设的驱动注册流程。第四,根文件系统:用 BusyBox 或 Yocto 构建最小根文件系统,配置 init 流程、网络和存储挂载。第五,开发调试:串口控制台、JTAG、GDB、内核日志与 ftrace 等手段的组合使用。第六,部署:将镜像写入 eNVM、SD 卡或 QSPI Flash,并验证启动结果。
为了便于后续章节对照,这里给出一个典型启动链的观察顺序。上电后,HSS 首先运行并初始化 DDR 与时钟;随后从 eNVM 或 SD 卡加载 U-Boot;U-Boot 读取 boot.scr 或环境变量,将内核镜像 Image 与设备树 mpfs.dtb 加载到 DDR 指定地址;内核解压后挂载根文件系统,执行 /sbin/init。判断启动是否成功,可以观察串口是否打印出内核版本、是否出现 Run /sbin/init as init process,以及最终是否进入登录提示符。若卡在 Starting kernel... 之后无输出,通常需要检查设备树中的 chosen 节点、串口波特率和 DDR 初始化参数。
需要特别强调的是,PolarFire SoC 的异构性决定了开发过程不能只关注软件或只关注硬件。设备树是软硬件之间的契约:fabric 设计者提供 IP 的地址范围与中断号,Linux 开发者据此编写节点和驱动。如果地址映射写错,驱动会读写到错误位置,表现为超时或数据异常;如果中断号不匹配,设备无法触发中断,表现为轮询可用但事件丢失。因此,本课程在每个实践环节都会同时给出硬件侧需要确认的信息和软件侧需要修改的文件,帮助建立“软硬协同”的调试直觉。