硬件平台: StarFive VisionFive V2 (LPDDR4 4GB)
目标操作系统: openEuler 22.03 LTS (RISC-V 64位)
U-Boot版本: U-Boot 2021.10 (May 07 2025 - 15:41:57 +0800), Build: jenkins-github_visionfive2_6.6-10
引言
本文记录了在StarFive VisionFive V2开发板上通过SD卡引导openEuler 22.03 LTS操作系统时遇到的启动故障及其排查和解决过程。参照系统在同一硬件上可成功引导Debian官方镜像,初步判断硬件本身工作正常,问题主要集中在U-Boot引导加载程序与openEuler镜像的兼容性或配置上。
初期故障现象与日志分析
使用串口对板卡开机日志进行监听,得到如下信息:
U-Boot SPL 2021.10 (May 07 2025 - 15:41:57 +0800)
LPDDR4: 4G version: g8ad50857.
Trying to boot from SPI
OpenSBI v1.2
/ __ \ / | _ _ |
| | | | __ ___ _ __ | ( | |) || |
| | | | '_ \ / _ \ '_ \ ___ | _ < | |
| || | |) | __/ | | |) | |) || |
_/| ./ _|| ||/|/___|
| |
|_|
Platform Name : StarFive VisionFive V2
Platform Features : medeleg
Platform HART Count : 5
Platform IPI Device : aclint-mswi
Platform Timer Device : aclint-mtimer @ 4000000Hz
Platform Console Device : uart8250
Platform HSM Device : —
Platform PMU Device : —
Platform Reboot Device : pm-reset
Platform Shutdown Device : pm-reset
Platform Suspend Device : —
Firmware Base : 0x40000000
Firmware Size : 392 KB
Firmware RW Offset : 0x40000
Runtime SBI Version : 1.0
Domain0 Name : root
Domain0 Boot HART : 1
Domain0 HARTs : 0*,1*,2*,3*,4*
Domain0 Region00 : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: ()
Domain0 Region01 : 0x0000000040000000-0x000000004003ffff M: (R,X) S/U: ()
Domain0 Region02 : 0x0000000040040000-0x000000004007ffff M: (R,W) S/U: ()
Domain0 Region03 : 0x0000000000000000-0xffffffffffffffff M: (R,W,X) S/U: (R,W,X)
Domain0 Next Address : 0x0000000040200000
Domain0 Next Arg1 : 0x0000000042200000
Domain0 Next Mode : S-mode
Domain0 SysReset : yes
Domain0 SysSuspend : yes
Boot HART ID : 1
Boot HART Domain : root
Boot HART Priv Version : v1.11
Boot HART Base ISA : rv64imafdcbx
Boot HART ISA Extensions : none
Boot HART PMP Count : 8
Boot HART PMP Granularity : 4096
Boot HART PMP Address Bits: 34
Boot HART MHPM Count : 2
Boot HART MIDELEG : 0x0000000000000222
Boot HART MEDELEG : 0x000000000000b109
U-Boot 2021.10 (May 07 2025 - 15:41:57 +0800), Build: jenkins-github_visionfive2_6.6-10
CPU: rv64imacu_zba_zbb
Model: StarFive VisionFive V2
DRAM: 4 GiB
MMC: sdio0@16010000: 0, sdio1@16020000: 1
Loading Environment from SPIFlash… SF: Detected gd25lq128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB
*** Warning - bad CRC, using default environment
StarFive EEPROM format v2
--------EEPROM INFO--------
Vendor : StarFive Technology Co., Ltd.
Product full SN: VF7110B1-2310-D004E000-00001763
data version: 0x2
PCB revision: 0xb2
BOM revision: A
Ethernet MAC0 address: 6c:cf:39:00:52:34
Ethernet MAC1 address: 6c:cf:39:00:52:35
--------EEPROM INFO--------
In: serial
Out: serial
Err: serial
Model: StarFive VisionFive V2
Net: eth0: ethernet@16030000, eth1: ethernet@16040000
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc1 is current device
Try booting from MMC1 …
Can’t set block device
Warning: Input data exceeds 1048576 bytes - truncated
Info: input data size = 1048578 = 0x100002
Error: “boot2” not defined
Card did not respond to voltage select! : -110
starfive_pcie pcie@2B000000: Port link up.
starfive_pcie pcie@2B000000: Starfive PCIe bus probed.
PCI: Failed autoconfig bar 10
starfive_pcie pcie@2C000000: Port link down.
starfive_pcie pcie@2C000000: Starfive PCIe bus probed.
PCI: Failed autoconfig bar 10
Device 0: unknown device
Device 0: unknown device
Tring booting distro …
switch to partitions #0, OK
mmc1 is current device
Try booting from MMC1 …
Can’t set block device
Warning: Input data exceeds 1048576 bytes - truncated
Info: input data size = 1048578 = 0x100002
Retrieving file: /extlinux/extlinux.conf
Can’t set block device
Error reading config file
Card did not respond to voltage select! : -110
Device 0: unknown device
Device 0: unknown device
StarFive #
观察到,系统引导失败时U-Boot输出的关键错误信息包括:
* *** Warning - bad CRC, using default environment: U-Boot环境变量存储区数据校验和错误,导致U-Boot加载其编译时内置的默认环境变量。
* Card did not respond to voltage select! : -110: 底层MMC子系统错误,表明U-Boot在与SD卡(设备mmc1)进行电压协商时失败。
* Can't set block device: 由于无法与SD卡正常通信,U-Boot无法将其初始化为块设备。
* Error reading config file (尝试读取 /extlinux/extlinux.conf): 块设备访问失败,导致无法读取引导配置文件。
针对环境变量CRC错误,首先在U-Boot命令行执行了以下操作:
env default -a
saveenv
reset
此操作成功重置并保存了默认环境变量,清除了CRC警告。然而,SD卡访问相关的 -110 错误依旧存在,系统仍无法从SD卡引导。
关键进展
考虑到Debian系统可正常引导,推测U-Boot的MMC驱动程序与SD卡在特定条件下能够兼容。尝试在U-Boot命令行手动与mmc1设备交互:
mmc dev 1 # 切换到 mmc1 (SD卡)
mmc rescan # 重新扫描MMC总线上的设备
mmc info # 显示当前MMC设备信息
在执行 mmc rescan 命令后,mmc info 成功返回了SD卡的详细信息(型号SC64G,容量59.5 GiB),且未出现 -110 错误。这一现象表明,在U-Boot的自动引导脚本中,可能在访问SD卡前缺少了必要的 mmc rescan 步骤,或者执行时序不当。
进一步,通过 mmc part 确认SD卡分区为GPT格式。使用 fatls mmc 1:2 /extlinux/ 命令,确认了引导配置文件 extlinux.conf 位于SD卡的第2分区(ESP分区,FAT32格式)。
U-Boot引导脚本分析
U-Boot的自动引导主要由 bootcmd 环境变量控制,其内容为:
bootcmd=run sdk_boot_env; run distro_boot_env
这表明引导流程依次执行 sdk_boot_env 和 distro_boot_env 两个脚本。通过 printenv 逐级分析这些脚本及其依赖的环境变量,关键信息如下:
boot_devs=mmc nvme: 定义了引导设备的尝试顺序。
bootmode=flash: U-Boot当前识别的启动模式为从SPI Flash启动(U-Boot本身由此加载)。
mmc_devnum_l=1 0: 当 bootmode=flash 时,脚本会遍历此列表中的MMC设备号(1对应SD卡,0对应eMMC)。
sdk_boot_env 和 distro_boot_env 的执行逻辑均依赖 bootmode,并针对 flash 模式下的MMC设备列表进行循环。
mmc_test_and_boot (由 bootenv_mmc 调用): 其内部包含 run boot2,是之前日志中 ## Error: "boot2" not defined 错误的来源。
distro_mmc_test_and_boot (由 distro_bootenv_mmc 调用): 其内容为 if mmc dev ${devnum}; then ... run bootcmd_distro;fi;。此处的 mmc dev ${devnum} 是自动引导时发生 -110 错误的关键点,因其后未立即执行 mmc rescan。
内核版本兼容性与引导分区定位
通过 fatls mmc 1:2 列出SD卡第2分区文件,发现:
* 内核文件为 vmlinuz-5.15.0-3.oe2203.riscv64。
* extlinux.conf 和 boot/uEnv.txt 也位于此分区。
此内核版本(5.15.0)与当前U-Boot(2021.10)自述文件中声明支持的内核版本之一相符,因此排除了内核版本不兼容作为首要原因的推测。
然而,检查到环境变量 bootpart 的值为 3 (通过 printenv bootpart),而 extlinux.conf 实际位于第 2 分区。这是导致后续 sysboot 命令(在 bootcmd_distro 内)无法找到配置文件的另一个关键原因。
手动引导验证
基于以上分析,在U-Boot命令行中手动设置正确的环境变量并执行引导序列:
mmc dev 1
mmc rescan
setenv devnum 1
setenv bootdev mmc
setenv bootpart 2 # 修正引导分区号为2
setenv boot_syslinux_conf extlinux/extlinux.conf
setenv bootenv boot/uEnv.txt
setenv loadaddr 0x50000000
setenv scriptaddr ${loadaddr}
# bootcmd_distro 的内容为: run load_distro_uenv; sysboot ${bootdev} ${devnum}:${bootpart} fat ${scriptaddr} /${boot_syslinux_conf};
run bootcmd_distro
此序列成功加载了所有引导组件,并最终启动进入openEuler系统,验证了问题点在于自动引导脚本的执行逻辑和参数错误。
解决方案
为实现自动引导,需将验证成功的逻辑固化到U-Boot环境变量中。
# 1. 将 boot2 定义为空操作,避免 sdk_boot_env 中的错误提示
setenv boot2 true
# 2. 定义针对SD卡 (mmc1) openEuler 的核心引导脚本 boot_oe_sd
setenv boot_oe_sd 'echo Attempting to boot openEuler from SD Card (mmc1)...; \
mmc dev 1; \
if test $? -eq 0; then \
mmc rescan; \
echo Setting boot parameters for mmc1 partition 2...; \
setenv devnum 1; \
setenv bootdev mmc; \
setenv bootpart 2; \
setenv boot_syslinux_conf extlinux/extlinux.conf; \
setenv bootenv boot/uEnv.txt; \
setenv loadaddr 0x50000000; \
setenv scriptaddr ${loadaddr}; \
echo Running bootcmd_distro...; \
run bootcmd_distro; \
else \
echo Failed to select mmc dev 1.; \
fi'
# 3. 修改主 bootcmd,使其首先尝试执行 boot_oe_sd
setenv bootcmd 'run boot_oe_sd; echo boot_oe_sd finished, falling back to original boot sequence if needed...; run sdk_boot_env; run distro_boot_env'
# 4. 保存环境变量至SPI Flash
saveenv
# 5. 重启系统
reset
执行以上命令后,VisionFive V2开发板成功实现了openEuler系统的自动引导。
结语
笔者以工业机器人控制为目的申请此板卡,并尝试使用OpenEuler 22.04 与ROS2 Humble进行应用开发,但遇到了新版Uboot固件无法正确引导OpenEuler 22.04的问题。虽然问题初步解决,但是此过程消耗了大量时间,对工业机器人项目进度造成了迟滞,且仍然存在无法使用HDMI显示图形界面的问题,在此背景下笔者选择了直接以Modbus/TCP协议与工业机器人通信的技术方案作为最终技术方案,并对uboot github开发组提出bug相关issue,在相关bug被完全解决后,对ROS2 Humble的尝试评测后续仍会进行,但受限于工时,可能内容将仅局限于基本的运动控制。
同时基于Modbus/TCP协议的应用开发在后续完成后也将一并奉上。

