香橙派Zero 3主线Linux移植避坑实录:手把手搞定BL31、Crust与U-Boot编译
香橙派Zero 3主线Linux移植避坑指南:BL31、Crust与U-Boot编译实战解析
最近在折腾香橙派Zero 3的全志H618芯片,想给它移植主线Linux系统。本以为照着官方文档一步步来就能轻松搞定,结果在BL31、Crust和U-Boot编译环节踩了不少坑。这篇文章就是我的踩坑实录,希望能帮到同样遇到问题的朋友。
1. 环境准备与工具链选择
在开始编译之前,环境配置是第一个容易出问题的地方。我最初使用的是Ubuntu 20.04,结果发现有些依赖库版本不够新,导致后续编译频频报错。后来换到Ubuntu 22.04才顺利通过。
必备工具清单:
- 交叉编译工具链(两个版本都需要):
gcc-arm-11.2-2022.02:用于编译TF-A、U-Boot和内核or1k-linux-musl:专门用于编译Crust固件
- 开发工具:
build-essential、bison、flex等基础编译工具libssl-dev:U-Boot编译必需device-tree-compiler:设备树处理工具
注意:工具链路径设置错误是新手最常见的错误之一。确保在编译每个组件前正确设置了PATH环境变量。
工具链版本兼容性对比表:
| 组件 | 推荐工具链 | 不兼容版本 | 典型错误表现 |
|---|---|---|---|
| BL31 | gcc-arm-11.2 | gcc-arm-8.x | 链接阶段失败 |
| Crust | or1k-linux-musl | 其他架构工具链 | 无法识别指令集 |
| U-Boot | gcc-arm-11.2 | gcc-arm-9.x | 设备树编译错误 |
2. BL31编译常见问题与解决
BL31作为ARM可信固件,是整个启动流程的第一环。全志H618的BL31编译有几个特别需要注意的地方。
典型错误1:PLAT参数选择不当
# 错误示例(会导致后续U-Boot无法正常加载) make PLAT=sun50i_h6 DEBUG=1 bl31 # 正确示例(H618应使用H616配置) make PLAT=sun50i_h616 DEBUG=1 bl31全志H618实际上是H616的超频版本,所以应该使用sun50i_h616平台配置。如果使用H6的配置,虽然能编译通过,但会导致后续U-Boot启动异常。
典型错误2:工具链路径未正确设置
# 必须确保工具链路径正确设置 export PATH=$PATH:/opt/gcc-arm-11.2/bin export CROSS_COMPILE=aarch64-none-linux-gnu-如果遇到类似"aarch64-none-linux-gnu-gcc: command not found"的错误,就是路径设置问题。建议使用绝对路径更可靠。
编译成功后,生成的BL31.bin文件位于:
build/sun50i_h616/debug/bl31.bin3. Crust电源管理固件编译陷阱
Crust是全志SoC特有的电源管理固件,编译过程有几个特别容易出错的地方。
问题1:错误的交叉编译链
# 必须使用or1k架构专用工具链 export PATH=$PATH:/opt/or1k-linux-musl/bin export CROSS_COMPILE=or1k-linux-musl-使用错误的工具链会导致编译失败,报错信息通常是无法识别的指令集。
问题2:配置文件选择不当
# 正确配置命令 make orangepi_3_defconfig && make -j$(nproc) scp虽然我们用的是Zero 3,但应该选择orangepi_3_defconfig而不是orangepi_zero3_defconfig,因为两者都是H6系列芯片,电源管理需求相似。
编译成功后,关键文件位于:
build/scp/scp.bin4. U-Boot编译与烧录实战
U-Boot是整个启动流程中最复杂的部分,也是问题最多的环节。
关键环境变量设置:
# 必须正确设置BL31和SCP路径 export BL31=/path/to/bl31.bin export SCP=/path/to/scp.bin # 或者如果不想使用电源管理功能 export SCP=/dev/null # 工具链设置 export PATH=$PATH:/opt/gcc-arm-11.2/bin export CROSS_COMPILE=aarch64-none-linux-gnu-编译命令:
make ARCH=arm orangepi_zero3_defconfig make ARCH=arm menuconfig # 可选,用于自定义配置 make ARCH=arm -j$(nproc)常见问题排查:
BL31未正确引用:如果启动时卡在BL31阶段,检查BL31路径是否正确,以及是否使用了适合H616的BL31版本。
设备树编译错误:如果遇到dtc相关的错误,尝试更新设备树编译器或检查设备树源文件是否有语法错误。
双重启动现象:有时U-Boot会启动两次,这通常是因为SPL和U-Boot配置不一致导致的,检查defconfig文件中的配置项。
烧录技巧:
# 烧录命令(注意seek=8参数很重要) sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8 conv=fsync烧录前确保TF卡已正确分区,建议至少分两个区:
- 第一个分区(FAT32):200MB,用于存放内核和设备树
- 第二个分区(EXT4):剩余空间,用于根文件系统
5. 调试技巧与高级问题解决
当系统无法正常启动时,串口调试是最有效的排查手段。香橙派Zero 3的调试串口是UART0,波特率115200。
常见启动问题分析:
卡在BL31阶段:
- 检查BL31是否针对H616正确编译
- 确认U-Boot中引用的BL31版本正确
电源管理异常:
- 如果系统无法正常关机/重启,检查Crust固件是否正确编译和引用
- 或者尝试
export SCP=/dev/null禁用电源管理
DDR初始化失败:
- 这通常表示BL31与硬件不兼容
- 尝试调整BL31中的DDR参数或使用更新的TF-A版本
性能优化建议:
- 在U-Boot配置中启用
CONFIG_ARM_CPU_SUSPEND可以改善电源管理 - 调整BL31中的CPU频率设置可以获得更好的性能
6. 实际项目中的经验分享
在最近的一个项目中,我们需要为香橙派Zero 3定制一个工业级Linux系统。除了基本的启动组件外,还需要考虑以下因素:
可靠启动方案:
- 使用冗余设计,在TF卡上保留两个U-Boot副本
- 实现启动失败后的自动回滚机制
生产环境优化:
# 生产环境烧录脚本示例 #!/bin/bash set -e echo "正在烧录U-Boot..." dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8 conv=fsync echo "正在验证烧录结果..." cmp -n $(stat -c%s u-boot-sunxi-with-spl.bin) u-boot-sunxi-with-spl.bin /dev/sdX -i 8192长期维护建议:
- 记录每次编译使用的确切版本号和配置
- 为每个版本保留完整的构建环境快照
- 使用git管理所有定制修改
