1. Stratix 10 SoC启动流程深度解析
在开始U-Boot和ATF编译之前,我们需要先深入理解Stratix 10 SoC的启动机制。与传统的FPGA+ARM架构不同,Stratix 10采用了更先进的异构计算架构,其启动流程也更为复杂。
1.1 启动流程关键阶段
Stratix 10 SoC的完整启动过程可以分为以下几个关键阶段:
-
SDM初始化阶段:系统上电后,安全设备管理器(Secure Device Manager)首先加载HPS EMIF IO配置,这是整个启动流程的基础。SDM会从配置的启动设备(如QSPI Flash)中读取初始配置信息。
-
FSBL加载阶段:SDM将HPS FSBL(First Stage Boot Loader)镜像加载到HPS的片上RAM中。这个阶段使用的是u-boot-spl.bin文件,它会被加载到HPS的0x00000000地址处。
-
SSBL执行阶段:FSBL初始化完成后,会从启动介质加载SSBL(Second Stage Boot Loader),也就是我们常说的U-Boot主程序。在Stratix 10上,这个文件是u-boot.itb。
-
操作系统加载阶段:U-Boot最后会加载Linux内核和根文件系统,完成整个启动流程。
1.2 关键文件作用解析
在整个启动流程中,有几个关键文件需要特别注意:
- sof文件:这是Quartus工具生成的FPGA配置文件,包含了FPGA的逻辑设计。
- u-boot-spl.bin:FSBL镜像,负责最基础的硬件初始化。
- u-boot.itb:SSBL镜像,即完整的U-Boot,提供更丰富的功能和接口。
- bl31.bin:ATF的Stage 3-1镜像,提供安全监控调用(SMC)和PSCI电源管理等服务。
提示:在实际开发中,建议先单独验证每个组件的功能,确保每个阶段都能正常执行,然后再进行整体集成。
2. 开发环境搭建与工具链配置
2.1 系统环境准备
根据我的实际经验,推荐使用以下开发环境配置:
- 操作系统:Ubuntu 22.04 LTS(长期支持版本稳定性更好)
- 开发工具:
- Quartus Prime Pro 25.1或更高版本
- ARM交叉编译工具链(gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu)
- 依赖库:
- build-essential(包含make、gcc等基础工具)
- python3(部分构建脚本需要)
- device-tree-compiler(设备树处理工具)
安装基础依赖的命令如下:
bash复制sudo apt update
sudo apt install -y build-essential python3 device-tree-compiler
2.2 交叉编译工具链配置
ARM架构的交叉编译工具链是开发过程中最重要的工具之一。以下是详细的配置步骤:
- 下载工具链:
bash复制wget https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/binrel/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
- 解压并设置环境变量:
bash复制tar xf gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
export PATH=`pwd`/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin:$PATH
export CROSS_COMPILE=aarch64-none-linux-gnu-
- 验证工具链是否安装成功:
bash复制aarch64-none-linux-gnu-gcc --version
注意:建议将环境变量设置添加到~/.bashrc文件中,这样每次打开终端时都会自动配置好工具链路径。
3. U-Boot源码获取与编译
3.1 源码获取与准备
Stratix 10使用的U-Boot源码可以从官方GitHub仓库获取:
bash复制git clone https://github.com/altera-fpga/u-boot-socfpga.git
cd u-boot-socfpga
建议使用与你的Quartus版本对应的U-Boot分支。例如,对于Quartus Prime Pro 25.1,可以使用socfpga_v2025.07分支:
bash复制git checkout socfpga_v2025.07
3.2 配置与编译过程
- 首先应用Stratix 10的默认配置:
bash复制make socfpga_stratix10_defconfig
这个命令会将configs/socfpga_stratix10_defconfig中的配置应用到当前目录的.config文件中。你可以使用以下命令查看配置差异:
bash复制diff -u configs/socfpga_stratix10_defconfig .config
- 开始编译:
bash复制make -j$(nproc)
编译过程中可能会遇到几个常见问题:
- 依赖缺失:如果提示缺少某些工具或库,使用apt安装即可。
- 时间同步问题:在WSL环境下可能会出现"Clock skew detected"警告,这是因为WSL和Windows系统时间不同步导致的。解决方法:
bash复制sudo apt install chrony
sudo systemctl restart chrony
- ATF缺失错误:这是正常现象,因为我们还没有编译ATF。错误信息通常如下:
code复制Image 'u-boot' is missing external blobs and is non-functional: blob-ext
Image 'u-boot' has faked external blobs and is non-functional: bl31.bin
3.3 编译产物分析
成功编译后,会在以下路径生成关键文件:
- spl/u-boot-spl.bin:FSBL镜像,用于初始硬件配置。
- u-boot.itb:SSBL镜像,包含完整的U-Boot功能。
- u-boot:ELF格式的可执行文件,主要用于调试。
可以使用以下命令检查u-boot.itb的内容:
bash复制./tools/dumpimage -l u-boot.itb
输出应该显示包含bl31.bin和u-boot的FIT镜像结构。
4. Arm Trusted Firmware(ATF)编译
4.1 ATF源码获取
ATF源码同样可以从官方GitHub仓库获取:
bash复制git clone https://github.com/altera-fpga/arm-trusted-firmware.git
cd arm-trusted-firmware
git checkout socfpga_v2.13.0
4.2 ATF编译步骤
- 清理之前的编译结果:
bash复制make PLAT=stratix10 clean
- 开始编译:
bash复制make PLAT=stratix10 all
编译完成后,关键文件位于build/stratix10/release目录下:
- bl31.bin:ATF的Stage 3-1镜像,提供安全监控服务。
- bl2.bin:ATF的Stage 2镜像,负责安全启动验证。
4.3 将ATF集成到U-Boot
将编译好的bl31.bin复制到U-Boot源码根目录:
bash复制cp build/stratix10/release/bl31.bin /path/to/u-boot-socfpga/
然后重新编译U-Boot:
bash复制cd /path/to/u-boot-socfpga
make distclean
make socfpga_stratix10_defconfig
make -j$(nproc)
这次编译应该能顺利完成,不再报错缺少bl31.bin。
5. 文件转换与JTAG加载准备
5.1 文件格式转换
为了使用JTAG加载启动,我们需要将生成的u-boot-spl.bin转换为HEX格式:
bash复制aarch64-none-linux-gnu-objcopy -O ihex spl/u-boot-spl spl/u-boot-spl.hex
这个HEX文件将与Quartus生成的sof文件一起打包,生成最终的HPS SOF文件。
5.2 JTAG加载流程
- 在Quartus中打开你的工程。
- 使用"Convert Programming Files"工具:
- 添加FPGA的sof文件作为输入
- 添加u-boot-spl.hex作为HPS镜像
- 生成最终的.jic或.sof文件。
- 使用Quartus Programmer通过JTAG接口加载到目标板。
注意:在实际操作中,可能会遇到JTAG连接不稳定的情况。建议使用高质量的JTAG调试器,并确保连接线不要太长。
6. 调试技巧与常见问题解决
6.1 调试UART配置
在开发初期,强烈建议启用UART调试输出。在U-Boot的SPL代码中(spl_s10.c),确保以下配置已启用:
c复制#ifdef CONFIG_DEBUG_UART
socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
debug_uart_init();
#endif
在defconfig文件中,确保以下配置存在:
code复制CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_SOCFPGA=y
6.2 常见问题排查
-
启动卡在FSBL阶段:
- 检查时钟配置是否正确
- 验证DDR初始化参数是否与你的板子匹配
- 确认FSBL是否正确加载到了片上RAM
-
ATF集成失败:
- 确保使用的ATF版本与U-Boot版本兼容
- 检查bl31.bin是否正确复制到了U-Boot目录
- 验证FIT镜像是否包含所有必要组件
-
JTAG加载问题:
- 检查JTAG连接是否可靠
- 确认sof文件和hex文件是否正确打包
- 验证目标板供电是否稳定
6.3 性能优化建议
-
编译速度优化:
- 使用
make -j$(nproc)充分利用多核CPU - 考虑使用ccache缓存编译结果
- 在SSD上存储源码和编译中间文件
- 使用
-
启动时间优化:
- 精简U-Boot功能,移除不需要的驱动和命令
- 优化DDR初始化参数
- 考虑使用更快的启动介质(如QSPI NOR Flash)
在实际项目中,我遇到过因为DDR参数不匹配导致系统不稳定的情况。通过仔细比对硬件设计文档和U-Boot中的配置参数,最终发现是tRFC参数设置不当。这个经验告诉我,在嵌入式开发中,硬件参数验证是至关重要的一环。
