searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

HPS(硬核处理器系统)开发 4——最小 HPS 系统软件与启动

2025-12-11 01:52:39
0
0

1. 最小 HPS 系统的启动链路回顾

以 Agilex 7 SoC 为例,一个完整的 HPS 启动链大致可以画成下面这样(示意图):
Mermaid Chart - Create complex, visual diagrams with text.-2025-12-10-083249.png

各阶段的典型职责大致如下:

  • BootROM / SDM器件内部固化的最早启动逻辑,根据引脚配置选择启动介质,加载第一阶段镜像(通常是包含 FSBL 的配置数据或 Flash 前几块区域)。

  • **FSBL(First Stage Boot Loader)**运行在 HPS 上,完成:

    • HPS 时钟 / 复位 / 外设的基础初始化;
    • DDR 控制器(HPS EMIF)的初始化和校准;
    • 根据指定介质(SD/eMMC/QSPI/NAND)加载 SSBL。
  • **SSBL(Second Stage Boot Loader,通常是 U‑Boot)**负责:

    • 提供命令行、脚本、网络(TFTP)等功能;
    • 加载 Linux 内核和设备树;
    • 传递启动参数(bootargs),跳转到内核入口。
  • Linux 内核 + 设备树 + RootFS
    完成操作系统层面的初始化,挂载根文件系统,启动 init 进程,最终给出 Shell 或图形界面。

在“最小 HPS 系统”的语境下,我们不追求外设的丰富度,只要求:

  • DDR 可用且稳定(FSBL 初始化成功);
  • 选定的启动介质可访问(SSBL 及 Linux 能够从中读取镜像);
  • 能通过串口看到完整的启动日志,并登录系统。

2. 为自定义硬件准备最小软件栈

有了第 3 篇中的硬件系统(HPS + DDR),接下来就要准备软件栈。根据项目情况,可以有不同的策略。

2.1 直接沿用 GSRD 的 U‑Boot / Linux(推荐起步方式)

如果上一篇你是先用官方 GSRD 在开发板上跑通了系统,然后再改成“最小 HPS 硬件”,那么可以沿用 GSRD 的软件栈,只做最小修改:

  • 保留原来的:
    • U‑Boot 源码和配置;
    • Linux 内核和根文件系统;
    • Yocto 或 Buildroot 工程;
  • 将第 3 篇生成的 硬件 handoff 文件(如 .sopcinfo / HPS handoff)导入,更新:
    • DDR 参数(容量、起始地址);
    • 设备树中的内存节点;
    • 必要的 HPS 外设配置。

这样可以最大程度复用官方验证过的启动链路,只把“硬件差异”通过 handoff / 设备树调整进去。

2.2 完全自定义的软件栈(适合深度定制)

如果项目对系统有较强的定制需求,也可以从零构建软件栈:

  • 使用 Intel 提供的示例 BSP、或者开源工程(如 linux-socfpga / u-boot-socfpga);
  • 使用 Yocto / Buildroot / 自己的构建脚本来生成:
    • FSBL;
    • U‑Boot;
    • Linux 内核;
    • 根文件系统(rootfs)。

无论是沿用 GSRD 还是从零构建,最终我们都需要拿到几类“成品文件”:

  • FPGA 配置:.sof(SRAM Object File);
  • 含有 FSBL 的 HPS 启动镜像(可能集成在比特流或独立二进制中);
  • U‑Boot 镜像:如 u-boot.bin / u-boot-spl.bin
  • Linux 内核:zImage / Image
  • 设备树:.dtb
  • 根文件系统:如 rootfs.ext4 / initramfs.cpio.gz 等。

接下来要做的,就是把这些东西“打包”成一个或若干可以烧录到板子上的镜像。


3. 使用 Programming File Generator 打包 jic

在自定义硬件上带起 HPS 系统的一种常见做法是:

利用 Quartus 的 Programming File Generator(Convert Programming Files),把 sof + FSBL + SSBL + 内核 + 根文件系统 打包成一个 jic 文件,然后一次性烧录到 Flash 中。

3.1 Convert Programming Files 基本流程

在 Quartus 中:

  1. 打开 File -> Convert Programming Files...
  2. Programming file type 中选择 JIC(JTAG Indirect Configuration);
  3. 选择目标器件和 Flash 类型(如 EPCQ / EPCQ-L / 第三方 SPI Flash 等);
  4. Input files to convert 区域中按顺序添加:
    • FPGA 配置文件 .sof
    • HPS 相关镜像(FSBL/SSBL/U‑Boot/内核/RootFS),通常是一个或多个 .bin
  5. 为每个输入文件设置:
    • 存放在 Flash 中的偏移地址;
    • 必要的选项(如是否压缩、是否带校验等)。

不同 SoC 器件的 jic 结构会略有差异,推荐直接参考对应的《Embedded Software Design Guide》中的示例布局。

3.2 一个典型的 jic 内容布局示意

可以把 jic 文件看作是“往 Flash 里排数据”的描述文件,例如:

[Flash 起始]
|-- FPGA 配置比特流(含 FSBL)
|-- U-Boot / SSBL
|-- Linux 内核 + 设备树
|-- 根文件系统(可选 / 可外置)
[Flash 结束]

烧录完成后,上电时的过程通常是:

  1. BootROM / SDM 从 Flash 指定位置加载 FPGA 配置比特流(其中包含 FSBL);
  2. FPGA 完成配置,HPS 触发 FSBL 运行;
  3. FSBL 从 Flash 其它偏移读取 U‑Boot,加载到 DDR;
  4. U‑Boot 继续从 Flash 或其它介质读取内核和根文件系统,最终启动 Linux。
3.3 选择启动介质与模式

在使用 jic 方案时,还需要配合板卡上的拨码/引脚设置 HPS 的启动介质:

  • 让 BootROM / SDM 知道:
    • 从哪块 Flash / SD 卡启动;
    • 是否先配置 FPGA 再启动 HPS,还是先 HPS 后 FPGA;
  • 对应的启动模式一般在器件手册中有详细说明(如 AS、JTAG、SD/eMMC、QSPI、NAND 等)。

在“最小 HPS 系统”的阶段,可以选一种最简单、最稳妥的组合,例如:

  • 用 JTAG 将 jic 烧录到板载 QSPI Flash;
  • 设置启动模式为:先从 QSPI 加载 FPGA 配置(带 FSBL),再从 QSPI 加载 U‑Boot / Linux

4. 板上启动与基本验证

在硬件 + 软件都准备好以后,就可以在板子上做一次“从 0 到 Shell” 的完整启动。

4.1 烧录 jic 到板载 Flash

使用 Quartus Programmer:

  1. 通过 USB‑Blaster 连接 JTAG;
  2. 选择目标链上的 SoC 设备;
  3. 添加刚刚生成的 *.jic 文件;
  4. 勾选 Program/Configure,执行烧录;
  5. 烧录成功后,断电重启(或复位)板子。
4.2 串口观察启动日志

使用串口终端(如 minicom / PuTTY)连接开发板 UART:

  • 设置波特率(一般为 115200 或 921600,视板卡而定);
  • 上电后观察输出:
    1. BootROM / SDM 初始信息(有的器件看不到);
    2. FSBL 初始化日志(DDR 初始化 / 校准是否成功);
    3. U‑Boot 启动信息(版本号、设备枚举等);
    4. Linux 内核启动日志(驱动加载、设备树解析、挂载根文件系统);
    5. 最终出现类似 login: 的登录提示。

如果在 FSBL 阶段就中断(常见表现是串口停在 DDR 初始化附近),大概率是:

  • HPS EMIF 配置与板卡 DDR 不匹配;
  • 硬件连线问题(DQ/DQS/CLK/ADDR 等);
  • DDR 供电/时钟不稳定。

这时需要回到第 3 篇的硬件配置,结合波形和板级测量排查问题。

4.3 登录系统并做最小自检

进入 Linux 后,可以做几项基本检查:

  • free -h / cat /proc/meminfo:确认 DDR 容量与预期一致;
  • dmesg:确认启动中没有严重错误(如 DDR ECC 错误、挂载失败等);
  • cat /proc/cpuinfo:确认 HPS 内核信息;
  • ls /dev:确认基础设备节点(UART、MMC、网口等)。

到这一步,说明“最小 HPS 系统”已经真正完整跑起来了。


5. 利用 Signal Tap 间接观测 HPS 专用引脚

在调试 HPS 启动问题时,很多人本能会想到用 Signal Tap 抓信号。但有一个现实限制:

HPS 专用引脚的信号(例如部分启动相关引脚)本质上不经过 FPGA 逻辑,因此无法直接用 Signal Tap 探测。

不过,我们仍然可以用一些“曲线救国”的办法,间接观察这些信号。

5.1 将 HPS 专用引脚信号路由到 FPGA 端

思路是:

  1. 在硬件设计中,将 HPS 专用引脚的信号(或者与之相关的状态)通过某种方式送入 FPGA 逻辑
  2. 在 FPGA 逻辑中再将这些信号接入 Signal Tap 采集端口;
  3. 通过分析 FPGA 端看到的波形,反推 HPS 侧的行为。

具体实现方式会因器件和引脚类型而不同,例如:

  • 对部分时钟/复位信号,可以在板级硬件上做简单的分配或缓冲,把同一个信号送到 FPGA 普通 I/O;
  • 对部分由 HPS 控制的片选 / 片上总线信号,可以在 Platform Designer 中通过桥接把状态寄存器暴露给 FPGA,再使用 Signal Tap 观测寄存器变化。
5.2 结合 JTAG-to-Avalon / System Console 进行寄存器级调试

除了波形级调试,还可以借助:

  • JTAG‑to‑Avalon Master:从 PC 端通过 JTAG 访问 FPGA 地址空间;
  • System Console:在 Tcl 环境下读写各种 Avalon 端口、寄存器。

配合 HPS↔FPGA 的桥接,可以做一些有用的事情:

  • 在 HPS 不正常启动时,从 FPGA 侧检查 DDR 控制器某些状态寄存器;
  • 手工发起一些访问,看是否能正确到达 HPS 或 DDR 区域。

这些手段虽然不如 JTAG 直连 HPS 核心那样“直观”,但在没有高阶调试器的情况下,足够帮助定位大部分硬件层面的启动问题。


6. 小结

本篇围绕“最小 HPS 系统”的软件与启动部分,完成了从抽象到落地的闭环:

  • 搭建在第 3 篇基础上的自定义硬件,准备 FSBL / U‑Boot / Linux / 根文件系统等软件组件;
  • 利用 Quartus 的 Programming File Generator,将 sof + 各种镜像 打包成 jic 并烧录到 Flash;
  • 上电通过串口观察完整启动过程,确认 DDR 和启动链路正常;
  • 利用 Signal Tap + JTAG‑to‑Avalon / System Console,在必要时对 HPS 启动相关信号做“间接观测”和寄存器级调试。

到这里,一个不依赖官方 GSRD,仅依赖芯片和板卡本身的最小 HPS 系统已经打通。从工程实践的角度看,它具备了:

  • 可移植到不同自定义板卡的通用性;
  • 足够精简的 IP 结构(HPS + DDR),便于分析和维护;
  • 后续可以逐步在 FPGA 侧挂载自定义逻辑,通过 HPS↔FPGA 桥接进行控制和数据交互。
0条评论
0 / 1000
Du_carry
6文章数
0粉丝数
Du_carry
6 文章 | 0 粉丝
原创

HPS(硬核处理器系统)开发 4——最小 HPS 系统软件与启动

2025-12-11 01:52:39
0
0

1. 最小 HPS 系统的启动链路回顾

以 Agilex 7 SoC 为例,一个完整的 HPS 启动链大致可以画成下面这样(示意图):
Mermaid Chart - Create complex, visual diagrams with text.-2025-12-10-083249.png

各阶段的典型职责大致如下:

  • BootROM / SDM器件内部固化的最早启动逻辑,根据引脚配置选择启动介质,加载第一阶段镜像(通常是包含 FSBL 的配置数据或 Flash 前几块区域)。

  • **FSBL(First Stage Boot Loader)**运行在 HPS 上,完成:

    • HPS 时钟 / 复位 / 外设的基础初始化;
    • DDR 控制器(HPS EMIF)的初始化和校准;
    • 根据指定介质(SD/eMMC/QSPI/NAND)加载 SSBL。
  • **SSBL(Second Stage Boot Loader,通常是 U‑Boot)**负责:

    • 提供命令行、脚本、网络(TFTP)等功能;
    • 加载 Linux 内核和设备树;
    • 传递启动参数(bootargs),跳转到内核入口。
  • Linux 内核 + 设备树 + RootFS
    完成操作系统层面的初始化,挂载根文件系统,启动 init 进程,最终给出 Shell 或图形界面。

在“最小 HPS 系统”的语境下,我们不追求外设的丰富度,只要求:

  • DDR 可用且稳定(FSBL 初始化成功);
  • 选定的启动介质可访问(SSBL 及 Linux 能够从中读取镜像);
  • 能通过串口看到完整的启动日志,并登录系统。

2. 为自定义硬件准备最小软件栈

有了第 3 篇中的硬件系统(HPS + DDR),接下来就要准备软件栈。根据项目情况,可以有不同的策略。

2.1 直接沿用 GSRD 的 U‑Boot / Linux(推荐起步方式)

如果上一篇你是先用官方 GSRD 在开发板上跑通了系统,然后再改成“最小 HPS 硬件”,那么可以沿用 GSRD 的软件栈,只做最小修改:

  • 保留原来的:
    • U‑Boot 源码和配置;
    • Linux 内核和根文件系统;
    • Yocto 或 Buildroot 工程;
  • 将第 3 篇生成的 硬件 handoff 文件(如 .sopcinfo / HPS handoff)导入,更新:
    • DDR 参数(容量、起始地址);
    • 设备树中的内存节点;
    • 必要的 HPS 外设配置。

这样可以最大程度复用官方验证过的启动链路,只把“硬件差异”通过 handoff / 设备树调整进去。

2.2 完全自定义的软件栈(适合深度定制)

如果项目对系统有较强的定制需求,也可以从零构建软件栈:

  • 使用 Intel 提供的示例 BSP、或者开源工程(如 linux-socfpga / u-boot-socfpga);
  • 使用 Yocto / Buildroot / 自己的构建脚本来生成:
    • FSBL;
    • U‑Boot;
    • Linux 内核;
    • 根文件系统(rootfs)。

无论是沿用 GSRD 还是从零构建,最终我们都需要拿到几类“成品文件”:

  • FPGA 配置:.sof(SRAM Object File);
  • 含有 FSBL 的 HPS 启动镜像(可能集成在比特流或独立二进制中);
  • U‑Boot 镜像:如 u-boot.bin / u-boot-spl.bin
  • Linux 内核:zImage / Image
  • 设备树:.dtb
  • 根文件系统:如 rootfs.ext4 / initramfs.cpio.gz 等。

接下来要做的,就是把这些东西“打包”成一个或若干可以烧录到板子上的镜像。


3. 使用 Programming File Generator 打包 jic

在自定义硬件上带起 HPS 系统的一种常见做法是:

利用 Quartus 的 Programming File Generator(Convert Programming Files),把 sof + FSBL + SSBL + 内核 + 根文件系统 打包成一个 jic 文件,然后一次性烧录到 Flash 中。

3.1 Convert Programming Files 基本流程

在 Quartus 中:

  1. 打开 File -> Convert Programming Files...
  2. Programming file type 中选择 JIC(JTAG Indirect Configuration);
  3. 选择目标器件和 Flash 类型(如 EPCQ / EPCQ-L / 第三方 SPI Flash 等);
  4. Input files to convert 区域中按顺序添加:
    • FPGA 配置文件 .sof
    • HPS 相关镜像(FSBL/SSBL/U‑Boot/内核/RootFS),通常是一个或多个 .bin
  5. 为每个输入文件设置:
    • 存放在 Flash 中的偏移地址;
    • 必要的选项(如是否压缩、是否带校验等)。

不同 SoC 器件的 jic 结构会略有差异,推荐直接参考对应的《Embedded Software Design Guide》中的示例布局。

3.2 一个典型的 jic 内容布局示意

可以把 jic 文件看作是“往 Flash 里排数据”的描述文件,例如:

[Flash 起始]
|-- FPGA 配置比特流(含 FSBL)
|-- U-Boot / SSBL
|-- Linux 内核 + 设备树
|-- 根文件系统(可选 / 可外置)
[Flash 结束]

烧录完成后,上电时的过程通常是:

  1. BootROM / SDM 从 Flash 指定位置加载 FPGA 配置比特流(其中包含 FSBL);
  2. FPGA 完成配置,HPS 触发 FSBL 运行;
  3. FSBL 从 Flash 其它偏移读取 U‑Boot,加载到 DDR;
  4. U‑Boot 继续从 Flash 或其它介质读取内核和根文件系统,最终启动 Linux。
3.3 选择启动介质与模式

在使用 jic 方案时,还需要配合板卡上的拨码/引脚设置 HPS 的启动介质:

  • 让 BootROM / SDM 知道:
    • 从哪块 Flash / SD 卡启动;
    • 是否先配置 FPGA 再启动 HPS,还是先 HPS 后 FPGA;
  • 对应的启动模式一般在器件手册中有详细说明(如 AS、JTAG、SD/eMMC、QSPI、NAND 等)。

在“最小 HPS 系统”的阶段,可以选一种最简单、最稳妥的组合,例如:

  • 用 JTAG 将 jic 烧录到板载 QSPI Flash;
  • 设置启动模式为:先从 QSPI 加载 FPGA 配置(带 FSBL),再从 QSPI 加载 U‑Boot / Linux

4. 板上启动与基本验证

在硬件 + 软件都准备好以后,就可以在板子上做一次“从 0 到 Shell” 的完整启动。

4.1 烧录 jic 到板载 Flash

使用 Quartus Programmer:

  1. 通过 USB‑Blaster 连接 JTAG;
  2. 选择目标链上的 SoC 设备;
  3. 添加刚刚生成的 *.jic 文件;
  4. 勾选 Program/Configure,执行烧录;
  5. 烧录成功后,断电重启(或复位)板子。
4.2 串口观察启动日志

使用串口终端(如 minicom / PuTTY)连接开发板 UART:

  • 设置波特率(一般为 115200 或 921600,视板卡而定);
  • 上电后观察输出:
    1. BootROM / SDM 初始信息(有的器件看不到);
    2. FSBL 初始化日志(DDR 初始化 / 校准是否成功);
    3. U‑Boot 启动信息(版本号、设备枚举等);
    4. Linux 内核启动日志(驱动加载、设备树解析、挂载根文件系统);
    5. 最终出现类似 login: 的登录提示。

如果在 FSBL 阶段就中断(常见表现是串口停在 DDR 初始化附近),大概率是:

  • HPS EMIF 配置与板卡 DDR 不匹配;
  • 硬件连线问题(DQ/DQS/CLK/ADDR 等);
  • DDR 供电/时钟不稳定。

这时需要回到第 3 篇的硬件配置,结合波形和板级测量排查问题。

4.3 登录系统并做最小自检

进入 Linux 后,可以做几项基本检查:

  • free -h / cat /proc/meminfo:确认 DDR 容量与预期一致;
  • dmesg:确认启动中没有严重错误(如 DDR ECC 错误、挂载失败等);
  • cat /proc/cpuinfo:确认 HPS 内核信息;
  • ls /dev:确认基础设备节点(UART、MMC、网口等)。

到这一步,说明“最小 HPS 系统”已经真正完整跑起来了。


5. 利用 Signal Tap 间接观测 HPS 专用引脚

在调试 HPS 启动问题时,很多人本能会想到用 Signal Tap 抓信号。但有一个现实限制:

HPS 专用引脚的信号(例如部分启动相关引脚)本质上不经过 FPGA 逻辑,因此无法直接用 Signal Tap 探测。

不过,我们仍然可以用一些“曲线救国”的办法,间接观察这些信号。

5.1 将 HPS 专用引脚信号路由到 FPGA 端

思路是:

  1. 在硬件设计中,将 HPS 专用引脚的信号(或者与之相关的状态)通过某种方式送入 FPGA 逻辑
  2. 在 FPGA 逻辑中再将这些信号接入 Signal Tap 采集端口;
  3. 通过分析 FPGA 端看到的波形,反推 HPS 侧的行为。

具体实现方式会因器件和引脚类型而不同,例如:

  • 对部分时钟/复位信号,可以在板级硬件上做简单的分配或缓冲,把同一个信号送到 FPGA 普通 I/O;
  • 对部分由 HPS 控制的片选 / 片上总线信号,可以在 Platform Designer 中通过桥接把状态寄存器暴露给 FPGA,再使用 Signal Tap 观测寄存器变化。
5.2 结合 JTAG-to-Avalon / System Console 进行寄存器级调试

除了波形级调试,还可以借助:

  • JTAG‑to‑Avalon Master:从 PC 端通过 JTAG 访问 FPGA 地址空间;
  • System Console:在 Tcl 环境下读写各种 Avalon 端口、寄存器。

配合 HPS↔FPGA 的桥接,可以做一些有用的事情:

  • 在 HPS 不正常启动时,从 FPGA 侧检查 DDR 控制器某些状态寄存器;
  • 手工发起一些访问,看是否能正确到达 HPS 或 DDR 区域。

这些手段虽然不如 JTAG 直连 HPS 核心那样“直观”,但在没有高阶调试器的情况下,足够帮助定位大部分硬件层面的启动问题。


6. 小结

本篇围绕“最小 HPS 系统”的软件与启动部分,完成了从抽象到落地的闭环:

  • 搭建在第 3 篇基础上的自定义硬件,准备 FSBL / U‑Boot / Linux / 根文件系统等软件组件;
  • 利用 Quartus 的 Programming File Generator,将 sof + 各种镜像 打包成 jic 并烧录到 Flash;
  • 上电通过串口观察完整启动过程,确认 DDR 和启动链路正常;
  • 利用 Signal Tap + JTAG‑to‑Avalon / System Console,在必要时对 HPS 启动相关信号做“间接观测”和寄存器级调试。

到这里,一个不依赖官方 GSRD,仅依赖芯片和板卡本身的最小 HPS 系统已经打通。从工程实践的角度看,它具备了:

  • 可移植到不同自定义板卡的通用性;
  • 足够精简的 IP 结构(HPS + DDR),便于分析和维护;
  • 后续可以逐步在 FPGA 侧挂载自定义逻辑,通过 HPS↔FPGA 桥接进行控制和数据交互。
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0