1. 项目概述
最近在OrangePi Zero2(全志H616平台)上折腾主线uboot、kernel和buildroot文件系统的移植工作,整个过程踩了不少坑,也积累了一些经验。作为一款性价比较高的开发板,OrangePi Zero2搭载全志H616四核Cortex-A53处理器,主频可达1.5GHz,非常适合用来学习嵌入式Linux系统开发。本文将详细记录从零开始移植主线uboot(2021.10版本)、Linux内核(6.6版本)和buildroot(2021.11版本)文件系统的完整过程。
为什么要选择主线版本而不是厂商提供的BSP?主线版本有更好的社区支持、更活跃的开发和更及时的安全更新。虽然初期移植工作会复杂一些,但长期来看维护成本更低。我在实际工作中发现,全志H616的主线支持已经相当完善,大部分基础功能都能正常工作。
2. 开发环境准备
2.1 硬件准备
- 开发板:OrangePi Zero2(全志H616)
- TF卡:建议使用Class10及以上速度的16GB容量卡,我实测使用低速卡会导致系统启动异常缓慢
- 串口调试工具:CP2102等USB转TTL模块,用于查看系统启动日志
- 电源:5V/2A电源适配器,H616在满载时功耗较高,劣质电源可能导致系统不稳定
2.2 软件环境
- 主机系统:Ubuntu 20.04 LTS(其他Linux发行版也可,但部分命令可能需要调整)
- 交叉编译工具链:gcc-aarch64-linux-gnu
- 必要工具:
bash复制sudo apt-get install build-essential git bison flex libssl-dev u-boot-tools
3. 主线uboot移植
3.1 获取交叉编译器
对于aarch64架构,我们需要安装对应的交叉编译工具链:
bash复制# 查看可用版本
apt-cache search aarch64
# 安装特定版本(这里选择gcc-10)
sudo apt-get install gcc-10-aarch64-linux-gnu
# 安装通用版本(会指向最新稳定版)
sudo apt-get install gcc-aarch64-linux-gnu
注意:建议同时安装特定版本和通用版本,某些构建系统可能只识别不带版本号的编译器名称。
验证安装是否成功:
bash复制aarch64-linux-gnu-gcc --version
3.2 获取ATF(ARM Trusted Firmware)
uboot需要ATF提供安全启动支持:
bash复制git clone https://github.com/ARM-software/arm-trusted-firmware.git
cd arm-trusted-firmware
make PLAT=sun50i_h616 DEBUG=1 bl31
编译完成后会生成build/sun50i_h616/debug/bl31.bin文件,后续uboot编译时需要用到。
3.3 编译uboot
获取uboot源码并编译:
bash复制git clone https://github.com/u-boot/u-boot.git
cd u-boot
git checkout v2021.10
# 配置
make orangepi_zero2_defconfig
# 编译(指定交叉编译器和ATF路径)
make CROSS_COMPILE=aarch64-linux-gnu- BL31=/path/to/bl31.bin
编译完成后会生成u-boot-sunxi-with-spl.bin文件,这就是我们要烧录的uboot镜像。
3.4 USB测试uboot
在烧录到TF卡前,可以先通过USB启动测试:
bash复制sudo sunxi-fel -v uboot u-boot-sunxi-with-spl.bin
如果连接了串口,可以看到uboot启动日志。这一步可以验证uboot是否正常编译。
3.5 烧录uboot到TF卡
3.5.1 TF卡分区
首先识别TF卡设备(假设为/dev/sdb):
bash复制sudo fdisk /dev/sdb
依次执行以下操作:
- 输入
o创建新的空DOS分区表 - 输入
n创建新分区(主分区,起始扇区2048,大小16M) - 输入
t设置分区类型为a2(Sunxi boot分区) - 输入
w保存并退出
3.5.2 格式化分区
bash复制sudo mkfs.vfat /dev/sdb1
3.5.3 烧录uboot
bash复制sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8
重要提示:seek=8参数很关键,这是全志芯片要求的uboot加载位置,错误的值会导致无法启动。
4. 主线内核移植
4.1 配置编译内核
获取Linux内核源码:
bash复制git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
git checkout v6.6
配置内核:
bash复制make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
在menuconfig中需要特别关注以下配置:
- Device Drivers > Graphics support > Sunxi Display Engine
- Device Drivers > USB support > DWC2 USB控制器
- Device Drivers > Network > Ethernet > Sunxi Gigabit Ethernet
编译内核:
bash复制make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
编译完成后会生成以下重要文件:
arch/arm64/boot/Image:内核镜像arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dtb:设备树文件
4.2 烧录内核到TF卡
4.2.1 TF卡分区
我们需要重新规划TF卡分区:
- 16MB - uboot分区(type a2)
- 128MB - kernel分区(type 83 Linux)
- 剩余空间 - rootfs分区(type 83 Linux)
可以使用fdisk或gparted工具完成分区。
4.2.2 写入内核文件
格式化kernel分区:
bash复制sudo mkfs.ext4 /dev/sdb2
挂载并复制文件:
bash复制sudo mount /dev/sdb2 /mnt
sudo cp arch/arm64/boot/Image /mnt/
sudo cp arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dtb /mnt/
sudo umount /mnt
5. 移植buildroot文件系统
5.1 配置buildroot
获取buildroot源码:
bash复制git clone https://git.buildroot.net/buildroot
cd buildroot
git checkout 2021.11
配置:
bash复制make menuconfig
关键配置项:
- Target options > Target Architecture = AArch64 (little endian)
- Toolchain > Toolchain type = External toolchain
- Toolchain > Toolchain = Custom toolchain
- Toolchain > Toolchain path = /usr/bin
- Toolchain > Toolchain prefix = aarch64-linux-gnu
- System configuration > Root filesystem overlay = 添加自定义配置
5.2 编译buildroot
bash复制make -j$(nproc)
编译完成后会在output/images/目录下生成rootfs.tar文件。
5.3 烧录文件系统
5.3.1 准备rootfs分区
bash复制sudo mkfs.ext4 /dev/sdb3
sudo mount /dev/sdb3 /mnt
sudo tar -xf output/images/rootfs.tar -C /mnt
sudo umount /mnt
5.3.2 配置uboot启动参数
在uboot环境中设置启动参数:
bash复制setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p3 rootwait
setenv bootcmd 'load mmc 0:2 0x40200000 Image; load mmc 0:2 0x4fa00000 sun50i-h616-orangepi-zero2.dtb; booti 0x40200000 - 0x4fa00000'
saveenv
6. 常见问题与解决方案
6.1 uboot无法启动
现象:串口无任何输出
排查:
- 检查电源是否稳定
- 确认uboot烧录位置正确(seek=8)
- 尝试通过USB启动测试
6.2 内核panic
现象:内核启动过程中崩溃
解决方案:
- 检查设备树文件是否正确
- 确认内核配置中启用了所有必要的驱动
- 尝试降低CPU频率(在uboot中设置)
6.3 网络不可用
现象:以太网无法连接
解决方案:
- 确认内核配置中启用了Sunxi Gigabit Ethernet驱动
- 检查设备树中的PHY配置
- 更新uboot中的网络环境变量
7. 性能优化建议
- CPU调频:H616支持动态调频,可以在
/etc/init.d中添加脚本设置合适的频率 - 内存优化:调整swappiness值减少交换分区使用
- IO优化:针对TF卡调整文件系统挂载参数(noatime,nodiratime)
整个移植过程大约花费了我3天时间,其中大部分时间都在调试各种外设驱动。主线的优势在于文档和社区支持都很完善,遇到问题通常能在邮件列表或论坛找到解决方案。对于想要深入学习嵌入式Linux开发的工程师,这种主线移植是非常有价值的实践。