Orange Pi Zero 3 使用全志H618芯片,基于ARM Cortex-A53架构。

整体流程概览

编译工具链 → 编译ATF → 编译U-Boot → 编译Linux内核 → 制作根文件系统(BusyBox) → 烧写SD卡

第一步:准备编译环境

在Ubuntu 22.04 x86_64主机上操作:

sudo apt update
sudo apt install -y \
  git make gcc bison flex bc \
  libssl-dev libncurses-dev \
  python3 python3-dev python3-setuptools \
  swig device-tree-compiler \
  gcc-aarch64-linux-gnu \
  binutils-aarch64-linux-gnu \
  u-boot-tools \
  parted dosfstools \
  wget unzip

设置交叉编译工具链环境变量:

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

第二步:编译 ARM Trusted Firmware (ATF/BL31)

H618需要ATF作为BL31,U-Boot依赖它:

git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
cd trusted-firmware-a

make PLAT=sun50i_h616 DEBUG=0 bl31
# 编译产物:build/sun50i_h616/release/bl31.bin

export BL31=$(pwd)/build/sun50i_h616/release/bl31.bin
cd ..

第三步:编译 U-Boot

git clone https://github.com/u-boot/u-boot.git
cd u-boot

# 使用 Orange Pi Zero 3 的默认配置
make orangepi_zero3_defconfig

# (可选)图形化配置
# make menuconfig

# 编译(指定BL31路径)
make -j$(nproc) BL31=$BL31

# 编译产物:u-boot-sunxi-with-spl.bin
ls -lh u-boot-sunxi-with-spl.bin
cd ..

第四步:编译 Linux 内核

git clone --depth=1 https://github.com/torvalds/linux.git
# 或者用orangepi官方内核(更推荐,驱动更完整):
# git clone --depth=1 https://github.com/orangepi-xunlong/linux-orangepi.git -b orange-pi-6.1-sun50iw9
cd linux   # 或 linux-orangepi

# 使用通用ARM64配置
make defconfig
# 或者用官方内核时用:
# make sun50iw9p1smp_defconfig

# 图形化裁剪内核(可选)
make menuconfig

# 编译内核镜像 + 设备树 + 模块
make -j$(nproc) Image dtbs modules

# 关键产物:
# arch/arm64/boot/Image          — 内核镜像
# arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dtb  — 设备树

第五步:制作根文件系统(BusyBox)

wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar xf busybox-1.36.1.tar.bz2
cd busybox-1.36.1

make defconfig

# 必须配置为静态链接(嵌入式系统推荐)
# Settings → Build static binary (no shared libs) → 选中
make menuconfig

make -j$(nproc)
make install  # 安装到 ./_install 目录

cd ..

构建完整根文件系统:

mkdir -p rootfs
cp -r busybox-1.36.1/_install/* rootfs/

# 创建必要目录
mkdir -p rootfs/{dev,proc,sys,tmp,etc/init.d,lib,lib64,usr/lib}

# 创建设备节点
sudo mknod rootfs/dev/console c 5 1
sudo mknod rootfs/dev/null    c 1 3
sudo mknod rootfs/dev/tty     c 5 0

# 创建 etc/fstab
cat > rootfs/etc/fstab << 'EOF'
proc      /proc   proc    defaults  0 0
sysfs     /sys    sysfs   defaults  0 0
tmpfs     /tmp    tmpfs   defaults  0 0
devtmpfs  /dev    devtmpfs defaults 0 0
EOF

# 创建启动脚本
cat > rootfs/etc/init.d/rcS << 'EOF'
#!/bin/sh
mount -a
mount -t devtmpfs devtmpfs /dev
echo "Welcome to OrangePi Zero3 Linux!"
hostname orangepi
EOF
chmod +x rootfs/etc/init.d/rcS

# 创建 inittab
cat > rootfs/etc/inittab << 'EOF'
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
EOF

# 安装内核模块到rootfs
cd linux  # 或 linux-orangepi
make modules_install INSTALL_MOD_PATH=../rootfs
cd ..

第六步:制作 SD 卡镜像并烧写

6.1 分区布局

SD卡布局:
┌─────────────────────────────────────────┐
│  0~7KB    : MBR / 保留                  │
│  8KB~1MB  : U-Boot (u-boot-sunxi-with-spl.bin)│
│  1MB~257MB: FAT32 分区 /boot (内核+dtb)  │
│  257MB~末 : ext4 分区 /  (根文件系统)    │
└─────────────────────────────────────────┘

6.2 创建镜像文件(推荐先用文件模拟,避免操作失误)

# 创建2GB空镜像
dd if=/dev/zero of=sdcard.img bs=1M count=2048

# 分区(FAT32 boot + ext4 rootfs)
parted sdcard.img --script \
  mklabel msdos \
  mkpart primary fat32  1MiB  257MiB \
  mkpart primary ext4   257MiB 100%

# 挂载为 loop 设备
sudo losetup -fP sdcard.img
LOOPDEV=$(sudo losetup -j sdcard.img | cut -d: -f1)
echo "Loop device: $LOOPDEV"

# 格式化
sudo mkfs.vfat -F32 -n BOOT ${LOOPDEV}p1
sudo mkfs.ext4 -L rootfs   ${LOOPDEV}p2

6.3 烧写 U-Boot

# U-Boot烧写到8KB偏移(SPL需要在扇区16)
sudo dd if=u-boot/u-boot-sunxi-with-spl.bin \
        of=$LOOPDEV \
        bs=1024 seek=8 conv=notrunc

6.4 写入内核和设备树到 boot 分区

sudo mkdir -p /mnt/boot /mnt/rootfs
sudo mount ${LOOPDEV}p1 /mnt/boot
sudo mount ${LOOPDEV}p2 /mnt/rootfs

# 复制内核和dtb
sudo cp linux/arch/arm64/boot/Image /mnt/boot/
sudo cp linux/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dtb /mnt/boot/

# 创建U-Boot启动脚本
cat > boot.cmd << 'EOF'
setenv bootargs "console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait rw"
load mmc 0:1 ${kernel_addr_r}  Image
load mmc 0:1 ${fdt_addr_r}     sun50i-h618-orangepi-zero3.dtb
booti ${kernel_addr_r} - ${fdt_addr_r}
EOF

# 编译为U-Boot可识别的脚本镜像
mkimage -C none -A arm64 -T script -d boot.cmd boot.scr
sudo cp boot.scr /mnt/boot/

6.5 写入根文件系统

sudo cp -a rootfs/* /mnt/rootfs/

# 卸载
sudo umount /mnt/boot
sudo umount /mnt/rootfs
sudo losetup -d $LOOPDEV

6.6 烧写到真实SD卡

# 确认你的SD卡设备名!!(极其重要,写错会损坏系统)
lsblk  # 插入SD卡前后对比,确认设备名,如 /dev/sdb 或 /dev/mmcblk0

# 烧写镜像
sudo dd if=sdcard.img of=/dev/sdX bs=4M status=progress conv=fsync
# 将 /dev/sdX 替换为你的实际SD卡设备
sync

第七步:启动和调试

7.1 串口连接

Orange Pi Zero 3 的调试串口(UART0):
TX → GPIO Pin 8
RX → GPIO Pin 10
GND → GPIO Pin 6
– 波特率:115200

# 主机上用 minicom 或 picocom 连接
sudo minicom -D /dev/ttyUSB0 -b 115200
# 或
sudo picocom -b 115200 /dev/ttyUSB0

7.2 预期启动日志

U-Boot SPL ...
U-Boot ...
=> (U-Boot命令行,或自动执行boot.scr)
Starting kernel ...
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
...
Welcome to OrangePi Zero3 Linux!
/ #

常见问题排查

现象 原因 解决
无任何串口输出 U-Boot未正确烧写/偏移错误 确认 seek=8(KB单位)
SPL启动后停止 BL31路径错误 重新编译U-Boot并指定BL31=
内核panic找不到rootfs root= 参数错误 改为root=/dev/mmcblk0p2
设备树找不到 dtb文件名错误 ls /mnt/boot/ 确认文件名
BusyBox报错缺少库 未静态编译 menuconfig中启用static binary

小贴士

  • 🔁 建议先用官方镜像确认硬件正常,再做手动编译
  • 🔧 如遇内核驱动不完整,推荐使用 OrangePi官方内核linux-orangepi 仓库)
  • 📦 根文件系统可以后续替换为 Alpine Linux 的 minirootfs 获得更完整的包管理器
  • 💾 整个流程建议在 Ubuntu 22.04 虚拟机或WSL2中操作

如有任何步骤遇到问题,欢迎告诉我具体报错信息!

发表评论