昉·星光2 RISC-V开发板U-Boot环境搭建与开发指南

昉·星光2 RISC-V开发板U-Boot环境搭建与开发指南

1. 昉·星光2单板计算机与U-Boot开发环境搭建

作为一名长期从事嵌入式开发的工程师,最近拿到昉·星光2(VisionFive 2)这块RISC-V架构的开发板时,内心还是有点小激动的。这款基于赛昉科技JH7110 SoC的单板计算机,可以说是目前RISC-V生态中性能最接近实用级别的开发平台之一。今天我要分享的是在这块板子上进行U-Boot开发的完整过程,特别是那些官方文档没有明确说明的细节问题。

首先明确几个关键点:JH7110是一颗四核64位RISC-V处理器,主频1.5GHz,支持DDR4/LPDDR4内存,而VisionFive 2板载了8GB内存和多种外设接口。U-Boot作为嵌入式系统的"第二段引导程序",负责初始化关键硬件、加载操作系统内核,其开发过程与传统的ARM平台有诸多不同。下面就从环境搭建开始,一步步解析RISC-V架构下的U-Boot开发要点。

1.1 开发工具链的选择与验证

在x86主机上为RISC-V架构交叉编译U-Boot,首要问题是选择正确的工具链。根据我的实测经验,目前有两种可行的方案:

  1. 预编译工具链:可以直接从SiFive官网获取预构建的交叉编译器,例如riscv64-unknown-elf-gcc。但需要注意版本兼容性问题,我推荐使用gcc版本10.x系列,太新的版本可能会遇到链接错误。
# 验证工具链是否可用 riscv64-unknown-elf-gcc --version # 预期输出应包含类似如下信息 # riscv64-unknown-elf-gcc (SiFive GCC-Metal 10.2.0-2020.12.8) 10.2.0
  1. Buildroot自定义构建:通过Buildroot系统构建完整的交叉编译环境,这种方法虽然耗时较长(首次构建可能需要1-2小时),但能确保所有工具链组件版本完全匹配。赛昉科技提供的SDK中就包含了Buildroot配置:
git clone https://github.com/starfive-tech/Tools.git cd Tools/buildroot make visionfive2_defconfig make

重要提示:无论采用哪种方式,务必确认工具链支持的ABI版本。JH7110需要rv64gc架构,即同时支持压缩指令(C)和原子指令(A)。可以通过以下命令验证:

riscv64-unknown-elf-gcc -march=rv64gc -mabi=lp64d -dM -E - < /dev/null | grep -i rv

1.2 获取官方U-Boot源码

赛昉科技维护了一个定制的U-Boot仓库,其中包含JH7110所需的特定驱动和配置。与主线U-Boot相比,这个版本增加了对StarFive系列芯片的完善支持:

git clone https://github.com/starfive-tech/u-boot.git -b JH7110_VisionFive2_devel cd u-boot

代码仓库的结构值得关注:

  • arch/riscv/cpu/jh7110:处理器特定的启动代码
  • board/starfive/visionfive2:板级支持包(BSP)
  • configs/starfive_visionfive2_defconfig:默认配置文件

1.3 开发主机环境配置

除了交叉编译器外,还需要准备以下工具:

  • device-tree-compiler:用于编译设备树文件
  • opensbi:RISC-V架构所需的监督二进制接口实现
  • swigpython3-dev:某些构建脚本的依赖项

在Ubuntu系统上可以通过apt一键安装:

sudo apt update sudo apt install device-tree-compiler swig python3-dev

对于OpenSBI,建议使用赛昉提供的预编译版本,或者从以下仓库构建:

git clone https://github.com/starfive-tech/opensbi.git -b JH7110_VisionFive2_devel cd opensbi make CROSS_COMPILE=riscv64-unknown-elf- PLATFORM=generic

2. U-Boot编译配置详解

2.1 默认配置解析

进入U-Boot源码目录后,首先加载默认配置:

make starfive_visionfive2_defconfig

这个配置文件中几个关键选项值得关注:

  • CONFIG_ARCH_RV64I=y:指定64位RISC-V架构
  • CONFIG_TARGET_STARFIVE_VISIONFIVE2=y:板级目标标识
  • CONFIG_SYS_MALLOC_LEN=0x800000:调整内存分配池大小
  • CONFIG_ENV_SIZE=0x20000:环境变量存储空间

2.2 内存布局与启动流程

JH7110的启动过程分为多个阶段:

  1. ROM Code:芯片内置的固化代码,从SPI Flash或eMMC加载TPL(初级程序加载器)
  2. TPL:初始化DDR控制器,加载SPL(二级程序加载器)
  3. SPL:进一步初始化外设,加载完整U-Boot
  4. U-Boot Proper:完整的引导加载程序

对应的内存映射如下:

0x40000000 - 0x4001FFFF: TPL运行区域(128KB) 0x40020000 - 0x4005FFFF: SPL运行区域(256KB) 0x40200000 - 0x402FFFFF: U-Boot运行区域(1MB)

2.3 定制化编译选项

根据实际需求,可能需要调整以下配置:

make menuconfig

几个常用修改项:

  • Boot延迟CONFIG_BOOTDELAY(默认为2秒)
  • 网络配置CONFIG_IPADDRCONFIG_SERVERIP
  • 文件系统支持CONFIG_FS_EXT4CONFIG_FS_FAT
  • USB设备支持CONFIG_USB_EHCI_HCD

修改后保存配置:

make savedefconfig cp defconfig configs/starfive_visionfive2_defconfig

3. 编译与烧写实战

3.1 完整编译流程

执行编译命令:

make CROSS_COMPILE=riscv64-unknown-elf- -j$(nproc)

关键输出文件:

  • u-boot.bin:原始二进制镜像
  • u-boot.img:带有头部信息的镜像
  • spl/u-boot-spl.bin:SPL阶段二进制
  • tpl/u-boot-tpl.bin:TPL阶段二进制

3.2 生成可烧写镜像

赛昉提供了打包工具fiptool,用于生成完整的启动镜像:

tools/fiptool.py create --tos FW_tee.bin \ --ntfw FW_bl31.bin \ --tpl build/tpl/u-boot-tpl.bin \ --spl build/spl/u-boot-spl.bin \ visionfive2_fw_payload.img

注意:FW_tee.binFW_bl31.bin需要从官方SDK中获取,它们是TrustZone相关的固件

3.3 烧写到SD卡

将镜像写入SD卡(假设SD卡设备为/dev/sdc):

sudo dd if=visionfive2_fw_payload.img of=/dev/sdc bs=1M conv=fsync sudo sync

分区布局应如下所示:

/dev/sdc1: FAT32分区(存放设备树和内核) /dev/sdc2: ext4分区(根文件系统)

4. 调试与问题排查

4.1 串口调试配置

VisionFive 2板载了调试串口,通过USB Type-C接口引出。在Linux主机上:

sudo picocom -b 115200 /dev/ttyUSB0

常见启动日志分析:

  • TPL阶段成功标志:DRAM: 8 GiB
  • SPL阶段成功标志:Loading Environment from MMC... OK
  • U-Boot阶段成功标志:Hit any key to stop autoboot

4.2 常见问题解决方案

问题1:DDR初始化失败现象:卡在Initialize DDR...阶段 解决方法:

  1. 检查board/starvfive/visionfive2/spl.c中的DDR参数
  2. 确认供电稳定,必要时外接电源

问题2:SPL加载失败现象:重复输出Trying to boot from MMC1解决方法:

  1. 检查SD卡镜像是否正确写入
  2. 尝试更换SD卡(某些品牌兼容性较差)

问题3:环境变量丢失现象:Bad CRC, using default environment解决方法:

  1. 在U-Boot命令行执行env save
  2. 检查CONFIG_ENV_OFFSETCONFIG_ENV_SIZE设置

5. 进阶开发技巧

5.1 自定义启动命令

通过修改include/configs/starvfive_visionfive2.h可以添加自定义命令:

#define CONFIG_EXTRA_ENV_SETTINGS \ "mycmd=echo Hello RISC-V\0" \ "bootargs=console=ttyS0,115200 root=/dev/mmcblk0p2 ro\0"

5.2 设备树修改与调试

提取当前设备树:

make CROSS_COMPILE=riscv64-unknown-elf- starfive_visionfive2.dtb

调试技巧:

# 在U-Boot命令行中 fdt list /cpus # 查看CPU节点 fdt resize 8192 # 调整设备树大小

5.3 性能优化建议

  1. 缩短启动时间

    • 禁用不必要的驱动(如USB、网络)
    • 调整CONFIG_BOOTDELAY为0
    • 使用CONFIG_SPL_FIT_IMAGE_TINY减小镜像尺寸
  2. 内存优化

    #define CONFIG_SYS_MALLOC_LEN (1024 * 1024) // 调整为实际需求 #define CONFIG_SYS_BOOTMAPSZ (64 * 1024 * 1024) // 引导内存区域
  3. 安全增强

    • 启用CONFIG_FIT_SIGNATURE进行镜像验证
    • 设置CONFIG_ENV_IS_NOWHERE防止环境变量被篡改

在实际项目中,我遇到过一个典型问题:当尝试从网络启动时,U-Boot会随机卡死。经过分析发现是DDR时序参数不够优化导致的,通过调整drivers/ram/starvfive/ddr_init.c中的ddr_cfg_phy结构体,最终解决了稳定性问题。这也提醒我们,在RISC-V这种新兴架构上开发,有时需要深入硬件层面对参数进行微调。