主要参考这两篇文章1.内核和根文件系统 2.uboot
一些需要的软件源码:
TF-A,arm可信固件
下载地址:https://github.com/ARM-software/arm-trusted-firmware
crust,全志电源管理固件
下载地址:https://github.com/crust-firmware/crust
uboot
下载地址:https://github.com/u-boot/u-boot
linux kernel
下载地址:https://github.com/torvalds/linux
buildroot
工具链:
交叉编译链:
1.gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu,用于编译tf-a、uboot、kernel等
下载地址:https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads/11-2-2022-02
2.or1k-linux-musl-cross,用于编译crust

用一个文件夹toolchain放相关的编译工具链
1.编译uboot相关代码
1.1编译arm信可固件
bash
# 设置交叉编译环境(沿用你之前的工具链)
export PATH=$PATH:~/Repo/linux/my_linux_in/toolchain/arm-gnu-toolchain-11.2/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin
export CROSS_COMPILE=aarch64-none-linux-gnu-
# 针对 Orange Pi Zero 3 的芯片 (sun50i_h616) 编译
make PLAT=sun50i_h616 DEBUG=0 bl31
编译成功后,
bl31.bin会在build/sun50i_h616/release/bl31.bin。
1.2编译crust
bash
# 进入 Crust 源码目录(你已经在了)
cd ~/Repo/linux/my_linux_in/crust
# 切换到 or1k 工具链
export PATH=$PATH:~/Repo/linux/my_linux_in/toolchain/or1k-gcc/bin
export CROSS_COMPILE=or1k-linux-musl-
# 配置并编译 Crust
make orangepi_3_defconfig
make
编译成功后,
scp.bin会在当前目录下生成,记下它的绝对路径。
1.3编译uboot
前面的步骤都是为了编译uboot
bash
cd ~/Repo/linux/my_linux_in/u-boot
# 设置 aarch64 工具链
export PATH=$PATH:~/Repo/linux/my_linux_in/toolchain/arm-gnu-toolchain-11.2/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin
export CROSS_COMPILE=aarch64-none-linux-gnu-
# 设置 BL31 和 SCP 路径(使用绝对路径)
export BL31=~/Repo/linux/my_linux_in/arm-trusted-firmware/build/sun50i_h616/debug/bl31.bin
export SCP=~/Repo/linux/my_linux_in/crust/build/scp/scp.bin
编译uboot:
bash
cd ~/Repo/linux/my_linux_in/u-boot
make orangepi_zero3_defconfig
make -j$(nproc)
编译结果为存放在uboot源码根目录下的
u-boot-sunxi-with-spl.bin文件
小tips:aarch64就是arm64
2.编译linux内核
2.1linux内核裁剪
请细看第一篇文章的内容,按那个内容裁剪内核
然后编译
bash
export PATH=$PATH:~/Repo/linux/my_linux_in/toolchain/arm-gnu-toolchain-11.2/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin
export CROSS_COMPILE=aarch64-none-linux-gnu-
make defconfig
编译完成后,会在arch/arm64/boot目录下生成Image和Image.gz文件,其中Image.gz文件即为旧版本kernel中的zImage,在arch/arm64/boot/dts/allwinner目录下生成sun50i-h618-orangepi-zero3.dtb,Image和设备树文件即可用来启动内核。
3.根文件系统构建
这里有两种选择:一是用buildroot,二是用ubuntu-base。我用的是buildroot(记得禁用linux内核和uboot的编译)
裁剪过程同样参考文章
或者可以用这个命令直接禁止kernel和uboot的编译:
bash
sed -i 's/^BR2_LINUX_KERNEL=y/# BR2_LINUX_KERNEL is not set/' .config
sed -i 's/^BR2_TARGET_UBOOT=y/# BR2_TARGET_UBOOT is not set/' .config
make olddefconfig
bash
make orangepi_zero3_defconfig # 加载板级配置
make -j20 # 20线程并行编译
编译,编译结果存放在
output\images目录下
4.TF卡烧录
先用
bash
lsblk
看一下tf卡的名字。像我的tf卡就是/dev/sdb
我们需要对tf卡进行分区,分为两个区,一个区放linux内核景象和设备树dtb,一个区放根文件系统
用fdisk工具分区
bash
# 1. 卸载所有分区(如果已挂载)
sudo umount /dev/sdb1 2>/dev/null
sudo umount /dev/sdb2 2>/dev/null
# 2. 擦除分区表
sudo dd if=/dev/zero of=/dev/sdb bs=1M count=1
# 3. 重新分区(使用 fdisk)
sudo fdisk /dev/sdb
# 依次输入:
# o (创建新的 DOS 分区表)
# n (新建分区)
# p (主分区)
# 1 (分区号 1)
# 回车 (默认起始扇区 2048)
# +100M (第一个分区大小 100MB,足够放 Image + dtb)
# t (修改分区类型)
# c (改为 FAT32 LBA)
# n (新建分区)
# p (主分区)
# 2 (分区号 2)
# 回车 (默认起始扇区)
# 回车 (默认结束扇区,占满剩余全部空间)
# w (保存退出)
# 4. 格式化两个分区
sudo mkfs.vfat -F 32 /dev/sdb1
sudo mkfs.ext4 /dev/sdb2
烧录uboot:
bash
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdb bs=1024 seek=8 conv=fsync
烧录内核、设备树、根文件系统:
bash
mkdir -p ~/tf_boot ~/tf_rootfs
sudo mount /dev/sdb1 ~/tf_boot
sudo mount /dev/sdb2 ~/tf_rootfs
sudo cp ~/Repo/linux/my_linux_in/linux/arch/arm64/boot/Image ~/tf_boot/
sudo cp ~/Repo/linux/my_linux_in/linux/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dtb ~/tf_boot/
sudo tar -xvf ~/Repo/linux/my_linux_in/buildroot/output/images/rootfs.tar -C ~/tf_rootfs/
sync
sudo umount ~/tf_boot
sudo umount ~/tf_rootfs
将tf插到开发板后,在uboot的启动阶段按任意键进入uboot命令行,输入:
bash
setenv bootcmd 'fatload mmc 0:1 0x40200000 Image;fatload mmc 0:1 0x4fa00000 sun50i-h618-orangepi-zero3.dtb;booti 0x40200000 - 0x4fa00000'
setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait rw init=/sbin/init debug panic=30'
saveenv
这段话的作用
自动找文件 → 从 SD 卡的第一个分区(FAT32)里,找到内核文件
Image和板子配置文件sun50i-h618-orangepi-zero3.dtb。自动搬进内存 → 把这两个文件从 SD 卡读取出来,放到内存的指定位置(
0x40200000和0x4fa00000)。自动启动内核 → 执行
booti命令,把 CPU 的控制权交给刚刚加载到内存里的 Linux 内核。内核自动挂载系统 → 内核启动后,严格按照
bootargs里的参数,去 SD 卡的第二个分区(/dev/mmcblk0p2)挂载根文件系统,最后启动你完整的 Linux 操作系统(比如 Debian/Ubuntu
我记得基本路径就是这样。可能有一些细节上的差错,后续会进行校对。