Firefly RK3399 - 从零构建TPL/SPL引导的U-Boot镜像
1. 环境准备与工具链安装
第一次接触Firefly RK3399开发板时,最让人头疼的就是搭建开发环境。记得当时我为了找个靠谱的交叉编译工具链,几乎翻遍了所有技术论坛。现在回想起来,其实整个过程并没有想象中那么复杂。
对于RK3399这种64位ARM架构的开发板,我们需要准备aarch64架构的交叉编译工具链。这里推荐直接从Arm官网获取最新版的Arm GNU Toolchain。具体操作步骤如下:
wget https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-none-linux-gnu.tar.xz sudo tar -xvf arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /usr/local/arm解压完成后,需要将工具链路径添加到系统环境变量。我习惯修改/etc/profile文件:
sudo vim /etc/profile # 在文件末尾添加 export PATH=/usr/local/arm/arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-none-linux-gnu/bin:$PATH # 保存后执行 source /etc/profile验证安装是否成功很简单,只需要运行:
aarch64-none-linux-gnu-gcc -v如果能看到类似"gcc version 13.2.1"的输出,说明工具链已经正确安装。
这里有个小技巧:建议把常用的交叉编译命令设置成别名,可以节省大量输入时间。我在~/.bashrc中添加了:
alias arm-make='make ARCH=arm CROSS_COMPILE=aarch64-none-linux-gnu-'2. 获取与配置U-Boot源码
U-Boot的版本选择很有讲究。经过多次尝试,我发现2023.07版本对RK3399的支持最为稳定。获取源码最直接的方式是从官方FTP下载:
wget https://ftp.denx.de/pub/u-boot/u-boot-2023.07.tar.bz2 tar -jxf u-boot-2023.07.tar.bz2 cd u-boot-2023.07配置阶段有几个关键点需要注意。首先是使用开发板默认配置:
make firefly-rk3399_defconfig然后进入menuconfig进行个性化调整:
make menuconfig在配置界面中,有几个重要选项需要特别关注:
- 串口波特率设置:Device Drivers → Serial → Default baudrate (115200)
- EMMC配置:需要关闭CONFIG_MMC_HS400_SUPPORT和CONFIG_MMC_SDHCI_SDMA,否则可能导致无法读取EMMC
- Boot delay设置:建议保留5秒等待时间方便调试
配置完成后,建议保存为自定义配置:
make savedefconfig cp defconfig configs/my-rk3399_defconfig3. 获取ATF可信固件
RK3399采用ARM Trusted Firmware(ATF)作为安全启动的基础。我们需要获取bl31.elf文件,这是连接BootROM和U-Boot的关键组件。
最直接的方式是从Rockchip官方GitHub仓库获取预编译好的bl31.elf:
git clone https://github.com/rockchip-linux/rkbin.git cp rkbin/bin/rk33/rk3399_bl31_v1.36.elf u-boot-2023.07/ mv rk3399_bl31_v1.36.elf atf-bl31如果想自己编译ATF,过程会稍微复杂些。需要先安装ARM嵌入式工具链:
sudo apt-get install gcc-arm-none-eabi git clone https://github.com/ARM-software/arm-trusted-firmware.git --depth 1 cd arm-trusted-firmware make CROSS_COMPILE=aarch64-none-linux-gnu- PLAT=rk3399不过根据我的经验,自己编译ATF经常会遇到各种依赖问题,对于新手来说直接使用官方预编译版本会更稳妥。
4. 编译U-Boot及问题排查
开始编译前,建议先安装必要的依赖:
sudo apt-get install python3-setuptools swig python3-dev python3-pip pip install pyelftools然后就可以开始编译了:
make ARCH=arm CROSS_COMPILE=aarch64-none-linux-gnu-在实际操作中,你可能会遇到以下常见问题:
问题1:权限不足导致编译失败
make[2]: *** [scripts/kconfig/Makefile:75:syncconfig] 错误 1解决方法:
sudo chmod 777 -R u-boot-2023.07问题2:缺少Python模块
ModuleNotFoundError: No module named 'setuptools'解决方法:
sudo apt-get install python3-setuptools问题3:缺少SWIG工具
unable to execute 'swig': No such file or directory解决方法:
sudo apt install swig问题4:缺少Python开发头文件
fatal error: Python.h: 没有那个文件或目录解决方法:
sudo apt install python3.8-dev问题5:缺少ELF工具
Python: No module named 'elftools'解决方法:
sudo apt install python3-pip pip install pyelftools成功编译后,会在目录下生成关键的中间文件,包括:
- tpl/u-boot-tpl.bin
- spl/u-boot-spl.bin
- u-boot.bin
5. 生成idbloader.img
idbloader.img是RK3399启动过程中第一个被加载的镜像文件,它由TPL和SPL两部分组成。生成过程分为两步:
首先生成基础镜像:
tools/mkimage -n rk3399 -T rksd -d tpl/u-boot-tpl.bin idbloader.img参数说明:
- -n rk3399:指定芯片型号
- -T rksd:指定为Rockchip SD卡启动镜像
- -d tpl/u-boot-tpl.bin:指定输入文件
然后将SPL部分追加到镜像中:
cat spl/u-boot-spl.bin >> idbloader.img验证镜像是否生成成功:
ls -lh idbloader.img正常情况下应该能看到一个几十KB大小的文件。
6. 生成u-boot.itb镜像
u-boot.itb是U-Boot的主镜像文件,采用FIT(Flattened Image Tree)格式。Rockchip提供了专门的脚本来生成这个文件。
首先需要获取Rockchip官方的U-Boot仓库:
git clone https://github.com/rockchip-linux/u-boot.git cp rockchip-linux/u-boot/arch/arm/mach-rockchip/make_fit_atf.py u-boot-2023.07/arch/arm/mach-rockchip/然后在menuconfig中启用FIT支持:
Boot options → Boot images → [*] Use a script to generate the .its script最后生成u-boot.itb:
make u-boot.itb ARCH=arm CROSS_COMPILE=aarch64-none-linux-gnu-这个过程可能会报一些警告,但只要最终生成了u-boot.itb文件就说明成功了。
7. 烧录镜像到开发板
Firefly RK3399支持多种烧录方式,最常用的是通过AndroidTool工具在Windows下烧录,或者直接在Linux系统下使用dd命令烧写。
方法一:使用AndroidTool烧录
- 让开发板进入Loader模式(按住Recovery键上电)
- 打开AndroidTool,选择生成的idbloader.img和u-boot.itb
- idbloader.img烧写到0x40扇区
- u-boot.itb烧写到0x4000扇区
- 点击"执行"开始烧录
方法二:在Linux下使用dd命令如果开发板已经运行Linux系统,可以直接使用dd命令烧写:
sudo dd if=idbloader.img of=/dev/mmcblk0 seek=64 sudo dd if=u-boot.itb of=/dev/mmcblk0 seek=16384 sync烧录完成后重启开发板,如果能在串口终端看到U-Boot的启动日志,说明整个过程成功了。第一次看到自己编译的U-Boot正常启动时,那种成就感真的难以形容。记得当时我反复重启了好几次,就为了确认这不是运气好碰巧成功了。
