1. 系列回顾与本文定位
在第一篇《概述》中,我们已经聊过:
- HPS 是什么,它在 SoC FPGA 里的角色;
- 两条典型路线:
- 用官方 GSRD 做“模板式”开发;
- 完全自定义 HPS + FPGA 系统,适配自研板卡。
本篇聚焦 GSRD 路线,目标只有三件事:
- 看懂 GSRD 工程里“硬件 + 软件”的基本结构;
- 用预编译镜像让开发板成功启动 Linux;
- 在此基础上实现一个最小的 HPS→FPGA “Hello World”。
先用一张总览流程图,看一下本篇的节奏(示意图):

2. 开发环境与资源准备
2.1 开发主机与操作系统
官方 GSRD 构建系统基于 Linux,推荐:
- 原生 Linux(Ubuntu / CentOS 等) 作为主要开发环境;
- 如果主要在 Windows 下工作,可以用 Windows + WSL 或 Linux 虚拟机,在里边构建镜像。
基本要求:
- 64 位系统;
- 剩余几十 GB 磁盘空间;
- 安装常见构建工具:
git、make、gcc、python等。
整个工具栈大致长这样(示意图):

2.2 必要工具与版本
结合 Agilex 7 SoC 的软件设计指南,一般会用到:
Quartus Prime Pro:编译 FPGA 设计、下载比特流;Platform Designer(Qsys):例化 HPS、EMIF、桥接和各类 IP;SoC EDS / Arm Development Studio:用于 U-Boot、Linux BSP 和调试;GSRD 参考工程 + Yocto 工具链:构建 Linux 内核和根文件系统。
GSRD 的 Yocto 工程会自动拉取:
linux-socfpga(内核);u-boot-socfpga(U-Boot);meta-intel-fpga-refdes、linux-refdesigns(参考设计配方和源码)。
2.3 获取 GSRD 工程与镜像
官方一般会提供:
- Quartus 工程 + Platform Designer 系统(
*_soc_hps.qsys等); - U-Boot / Linux / RootFS 的构建脚本或 Yocto 配方;
- 一份可直接烧录的 SD 卡镜像。
建议第一次上手时:先用 预编译镜像 跑通,再考虑自己重新构建 U-Boot、内核和 RootFS。
2.4 硬件连接与调试接口
以常见的 Intel SoC 开发板为例,至少准备:
- JTAG(USB-Blaster):烧录 FPGA 配置、JTAG 调试;
- 串口(UART):查看启动日志、登录 Linux;
- 以太网:后续远程登录、传文件;
- SD/eMMC:作为 HPS 启动介质,存放 GSRD 镜像。
上电前务必检查:
- FPGA 配置模式(AS / JTAG 等)是否与使用方法一致;
- HPS Boot 介质是否指向 SD/eMMC,而不是 QSPI 或 NAND,否则可能串口无任何输出。
3. GSRD 工程结构快速解读
GSRD 工程可以简单理解为:一套已经帮你搭好的 HPS+FPGA SoC 硬件系统 + 对应的软件栈。先从结构上“扫一眼”,再进细节。
3.1 硬件工程:Quartus + Platform Designer
在 Quartus 工程中通常会看到:
- 顶层设计文件(Verilog/VHDL):管脚、时钟、复位;
- 一个 Platform Designer 系统:例化 HPS、EMIF、桥接 IP、外设 IP 等。
可以用一张小图来理解 GSRD 的硬件结构(示意图):

Platform Designer 的使用套路很固定:
- 从 IP 目录中选择并配置 HPS、EMIF、PIO、桥接等组件;
- 把各个 Avalon/AXI 接口连起来;
- 运行连线/地址检查,消除冲突;
- 生成 HDL,在 Quartus 顶层实例化。
针对官方开发板,Intel 通常还会给一份 board XML:
- 自动带出 HPS 的 DDR 通道参数;
- 自动绑好 UART / EMAC / SDMMC / JTAG 等外设引脚;
- 自动给出必要的时钟、复位和引脚约束。
这样做的好处是:第一次使用时几乎不用碰复杂的 EMIF 和 HPS 配置,就能拿到一套“安全可用”的硬件工程。
3.2 软件工程:启动链与镜像组成
Agilex 7 SoC 的软件启动链可以画成一条“接力棒”(示意图):

各阶段职责简单归纳:
- BootROM / SDM:加载 FPGA 配置比特流;比特流中通常包含 HPS 的 FSBL。
- FSBL:完成 HPS 初始化(MPU、互连、DDR、启动介质控制器等),从外部闪存/SD 卡中加载 SSBL。
- SSBL(通常是 U-Boot):提供命令行、脚本、网络 TFTP 等功能,加载 Linux 内核、设备树和 RootFS。
- Linux:挂载根文件系统,启动服务和示例应用,为用户提供 Shell 或图形界面。
Intel 在软件指南里明确建议:
- 不要自己从零写引导加载程序;
- 尽量在现有 FSBL/U-Boot 的基础上做修改(例如调整启动介质、内存大小等)。
3.3 HPS 与 FPGA 的互连:本篇实际用到什么
关于 MPU / Non-MPU 视图、各类桥接接口和 L3 互连重映射,在《HPS 地址映射》那篇文章里已经详细展开,这里只保留本篇用得上的最小知识:
- 在 GSRD 里,HPS 和 FPGA 之间主要通过两类总线互连:
HPS2FPGA:高带宽 AXI 接口,适合大数据通道;LWHPS2FPGA:轻量级接口,适合访问寄存器类 PIO / 控制寄存器。
- 在 Platform Designer 里,对应的 master 端口分别是:
h2f_axi_master(连到 HPS2FPGA);h2f_lw_axi_master(连到 LWHPS2FPGA)。
- 在 Platform Designer 内部,每个 FPGA 从设备(如 PIO)都有一个 本地偏移地址,HPS 真正访问时遵循一个公式:
HPS 访问地址 = HPS 侧桥接基址 + Qsys 内部偏移
本篇后面的 “HPS–FPGA Hello World” 会直接用这个公式推导 LED 寄存器地址;更完整的地址空间结构,可参考已发布的《HPS 地址映射》。
把本篇会用到的互连关系画成一张小图,大致如下(示意图):

4. 从出厂工程到“能跑起来”的系统
这一节的目标是:不改任何配置,先让开发板用官方 GSRD 镜像顺利跑起来。
4.1 写入 SD 卡镜像
假设手上有一个类似 gsrd-agilex7-soc-*.sdcard 的镜像文件,可以在 Linux 下这样处理:
- 插入 SD 卡,用
lsblk或dmesg确认设备节点(如/dev/sdX); - 使用
dd写镜像:sudo dd if=gsrd-agilex7-soc.sdcard of=/dev/sdX bs=1M status=progress sync - 重新拔插 SD 卡,确认分区:
- 启动分区(FAT):放 FSBL / U-Boot / 内核 / 设备树等;
- 根文件系统分区(ext4):放
/sbin、/lib、/home等。
在 Windows 下也可以用图形工具(如 balenaEtcher)直接写入 .sdcard / .img。
4.2 配置启动模式并上电
开发板上常见的与启动相关的拨码包括:
- FPGA 配置模式(AS / JTAG 等):决定 FPGA 比特流从哪来;
- HPS 启动介质(SD/eMMC、QSPI、NAND 等):决定 FSBL/SSBL 从哪读。
对于 GSRD,比较常见的一种搭配是:
- 用 JTAG 或 AS 为 FPGA 预烧录“带 FSBL 的比特流”;
- 让 HPS 从 SD/eMMC 启动 U-Boot(SSBL)和 Linux 系统。
也就是下面这条“接力棒”,只不过这次是真实板子上的启动(示意图):

具体拨码位置需要查对应开发板的用户手册;如果上电后串口完全没输出,第一件事就是检查这些开关。
4.3 启动日志与登录系统
串口终端里正常的启动过程大致如下:
- BootROM / SDM 输出少量信息(有时不可见);
- FSBL 初始化 HPS 和 DDR,加载 U-Boot;
- U-Boot 打印版本信息,执行环境脚本,从 SD 卡加载内核和设备树;
- Linux 内核启动,枚举外设,最终交给
init; - 出现登录提示(如
agilex7-soc login:)。
GSRD 镜像一般提供 root 账户,常见配置是 root 无密码(以官方文档为准)。
4.4 基础功能自检
登录后,可以简单做几项检查确认系统健康:
- 网络:
ip a查看网口是否正常、ping网关或 PC; - 存储:
df -h查看根文件系统挂载情况,确认 SD/eMMC 分区; - 外设:
dmesg查 UART / I2C / SPI / USB 是否有异常; - 板载资源:运行 GSRD 自带 demo(如 LED 闪烁),确认 HPS 能访问 FPGA 逻辑。
这一步的结论只有一个:出厂 GSRD 工程 + 官方镜像工作正常,后面再动手改东西心里就比较有底。
5. 基于 GSRD 的 HPS–FPGA “Hello World”
在系统跑通后,就可以在 GSRD 上做一个最小的 HPS→FPGA 交互示例。
思路:
在 FPGA 里做一个 LED 寄存器,通过 LWHPS2FPGA 暴露给 HPS,HPS 在 Linux 用户态用
/dev/mem直接读写,点亮板上的 LED。
5.1 在 Platform Designer 中添加最小逻辑
以 GSRD 自带的 Platform Designer 系统为起点:
- 打开
*.qsys工程,找到hps组件和h2f_lw_axi_master接口; - 从 IP 目录添加一个
PIO:- 宽度设为 8 或 32 位;
- 方向设为输出;
- 命名为
led_pio;
- 把
led_pio的寄存器接口挂到h2f_lw_axi_master上,在地址编辑器中分配偏移(如0x00000000); - 重新生成系统 HDL,并在 Quartus 顶层把
led_pio输出连到开发板 LED 引脚; - 全编译工程,通过 JTAG 烧录新的 SOF 到 FPGA。
此时:
- 在 Platform Designer 视角,
h2f_lw_axi_master的地址从0x00000000开始; led_pio占用了其中最前面的一小段地址。
5.2 从 HPS 视角理解地址
在《HPS 地址映射》文章中,已经详细讲过 HPS2FPGA / LWHPS2FPGA 的地址空间,这里只用到一个结论:
- 在 MPU 视角,
LWHPS2FPGA通常映射到一个固定基址(典型值是0xFF200000); - 在 Platform Designer 中,我们让
led_pio放在0x00000000偏移; - 所以,HPS 访问 LED 寄存器的物理地址 =
0xFF200000 + 0x00000000。
实际项目中,推荐:
- 利用 Platform Designer 的地址导出功能 + Intel 文档确认准确基址;
- 在工程文档/代码中统一整理这些地址,避免人为记错。
5.3 在 Linux 用户态读写 FPGA 寄存器
在 GSRD 的 Linux 里,可以先用最直接的 /dev/mem + mmap 实现 Demo(示例代码):
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>
#include <unistd.h>
#define LW_H2F_BASE 0xFF200000UL
#define LW_H2F_SPAN 0x00001000UL
#define LED_PIO_OFFSET 0x0
int main(void) {
int fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) return -1;
void *lw_base = mmap(NULL, LW_H2F_SPAN,
PROT_READ | PROT_WRITE,
MAP_SHARED, fd, LW_H2F_BASE);
if (lw_base == MAP_FAILED) return -1;
volatile uint32_t *led_pio =
(uint32_t *)((uint8_t *)lw_base + LED_PIO_OFFSET);
// 点亮部分 LED
*led_pio = 0x0F;
sleep(1);
*led_pio = 0xF0;
munmap(lw_base, LW_H2F_SPAN);
close(fd);
return 0;
}
把这段代码在开发板上编译、运行,如果 LED 能按预期亮灭,说明:
- HPS 上的 Linux 正常运行;
- LWHPS2FPGA 桥打通;
- Platform Designer 中的寄存器映射与 HPS 地址空间匹配。
数据路径画出来,大致就是这样(示意图):

5.4 常见问题与排查
如果 “Hello World” 没按预期工作,可以从下面几个角度排查:
- 地址是否写错:HPS 基址 + Qsys 偏移 是否算对;
- 缓存影响:必要时关闭该区域缓存,或确保使用
volatile和适当的内存屏障; - 时钟/复位:确认 PIO 所在时钟域已使能、复位已释放;
- 比特流:确认最新编译的 SOF 已经成功烧录到板子;
- 桥接开关:有些芯片默认关闭 FPGA Slaves,需要在启动代码中显式打开。
辅助工具:
- 利用 System Console 或 JTAG-to-Avalon Host Bridge,从 PC 直接访问 FPGA 寄存器,对比 HPS 侧读写结果;
- 用 Signal Tap 看 HPS2FPGA 总线上的地址、数据是否正确;
- 用 Arm DS 等调试器,在 HPS 侧单步执行访问寄存器的代码,观察是否触发异常。
6. 在 GSRD 上做“小改动”的标准流程
“Hello World” 跑通之后,通常会逐步把 GSRD 改成自己的工程。比较安全的做法是:
先在硬件工程里做局部改动,再导出硬件信息驱动软件更新,保持与原始 GSRD 的“最小差异”。
6.1 硬件侧:哪些改动比较安全?
在基于开发板的场景中,相对安全的改动包括:
- 在 Platform Designer 中增加少量 FPGA 侧 IP(PIO、简单 AXI 从设备、DMA 等),通过 HPS2FPGA 或 LWHPS2FPGA 访问;
- 适度开启 HPS 组件中的额外外设实例(I2C / SPI 等),前提是板级确实有连线;
- 修改 FPGA 内部逻辑,不改 HPS 与外设之间的管脚分配。
而以下改动则需要更谨慎:
- 修改 EMIF/DDR 参数(速率、位宽、拓扑);
- 调整 HPS 外设的管脚绑定(UART、EMAC、SDMMC 等);
- 大幅度调整时钟架构或 PLL 参数。
这些改动往往影响 FSBL / U-Boot 的早期初始化,建议在充分理解官方文档(如 EMIF IP 用户指南、HPS 地址映射与时钟树)后再动手,并配合仿真和板级验证。
6.2 从硬件到软件:BSP 与设备树的闭环
当 Platform Designer 结构发生变化(新增外设、改变地址映射等),软件侧需要“感知”这些变化。典型步骤:
- 在 Quartus / Platform Designer 中导出硬件描述(
.sopcinfo或 HPS handoff 文件); - 使用 SoC EDS / 脚本,根据硬件描述重新生成:
- U-Boot / Linux 的 BSP;
- 设备树(
*.dts/*.dtb);
- 重新编译 U-Boot、Linux 内核,或至少更新设备树;
- 把新的镜像写回 SD 卡启动分区,在板上验证。
可以用一张流程图记住这个闭环(示意图):

Intel 的 GSRD Yocto 工程(meta-intel-fpga-refdes 等)对参考设计做了不少自动化,建议:
- 尽量在原有配方基础上“轻量修改”;
- 避免在 Yocto 层大面积硬编码板级细节,以免后续难以维护。
6.3 保持与官方工程的“最小差异”
在项目早期,可以考虑:
- 给官方 GSRD 工程建 Git 仓库,所有改动通过分支或补丁记录;
- 不随意删除官方 IP 和软件组件,而是采用“旁路式”添加自己逻辑;
- 每次只做一类改动(例如“新增一个 PIO + 对应驱动”),单独完成验证,避免多个改动堆在一起难以排错。
7. 小结
本篇围绕 GSRD 这条“官方模板路线”,完成了三步:
- 通过几张小图,把 GSRD 的硬件结构、软件启动链和 HPS–FPGA 互连关系串起来;
- 用预编译 GSRD 镜像,让开发板成功启动 Linux,并完成基础自检;
- 在 GSRD 上实现了一个最小的 HPS→FPGA “Hello World”,并给出从硬件到软件更新的小改动流程。
GSRD 的优势:
- 开箱即用、验证充分,适合入门和原型验证;
- 问题容易对照官方文档和示例定位。
局限也很明显:
- 强依赖官方开发板拓扑,不易直接迁移到自定义硬件;
- 部分旧工具(如 SoC EDS)已停止更新,新器件更多依赖开源工具链和新文档。