
前情提要
基于现有的开发环境(Windows 电脑 +Ubuntu 电脑)进行编译,不安装虚拟机,不使用 PetaLinux,直接使用源码和通用编译链工具进行编译。这样做的好处是所有的地方都可以自定义,对于编译的过程会有更加深刻的理解,并且编译方法更加底层,对于后续移植到国产 fpga 上有很大帮助。声明:以下全部内容为本人依据 AI 指导以及查询网络资料完成,如遇各种报错信息请询问 AI,绝大部分都可以解决。
准备工作
vivado 工程
创建最小工程,选定开发板上的 sd 卡和 uart 串口,注意跟原理图保持一致,对于黑金 7020,选择 SD0 和 UART1. 注意 vivado 默认的 SD 卡的两个配置引脚是错误的,Card Detect 要根据原理图或者用户手册进行修改,黑金 7020 要改为 MIO47,写保护一定要去掉。

搭建一个最小系统,参考火火的文章(ZYNQ 芯片 ARM 端 HelloWorld 最小程序 - 知乎). 生成比特,导出 hardware,创建一个 sdk 工程。
SDK 工程
- 创建 FSBL 工程,编译得到文件
FSBL.elf. - 创建设备树文件,File->New->Board Support Package, 选择 device_tree,点击 finish,得到文件
system-top.dts.
uboot 和 Linux 编译
-
安装交叉编译器和其它依赖
sudo apt-get update sudo apt-get install git make gcc-arm-linux-gnueabihf u-boot-tools device-tree-compiler libncurses5-dev -
下载 uboot 和 Linux 内核源码
mkdir your_path cd your_path git clone https://github.com/Xilinx/u-boot-xlnx.git git clone https://github.com/Xilinx/linux-xlnx.git -
进入仓库,选择对应的版本,本文使用 2022.1 版本,标签为 xilinx-v2022.1,该版本与 sdk 和 vivado 版本无直接关联。
-
安装 gcc-linaro-7.5.0-2019.12 编译工具链。
mkdir -p ~/tools # 创建文件夹存放工具链 cd ~/tools sudo wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz # 下载工具链 sudo tar -vxf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz # 解压工具链
编译
u-boot 编译
进入 uboot 文件夹并配置交叉编译器环境变量
cd your_path/u-boot-xlnx
export CROSS_COMPILE=arm-linux-gnueabihf-
找到合适的配置文件
ls configs/xilinx_zynq_*_defconfig
输入以上指令会看到 configs/xilinx_zynq_virt_defconfig 的输出,这就是我们需要的配置文件,但是需要做出修改,主要的修改项是第 9 行的 CONFIG_DEFAULT_DEVICE_TREE,默认选择的设备树是 zynq-zc706,对于黑金 7020,需要将其修改为 zynq-zc702
vim configs/xilinx_zynq_virt_defconfig
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" ----修改这里----
保存后进行编译
make xilinx_zynq_virt_defconfig # 选择配置文件
make -j4 # 编译u-boot
编译成功后,会在 u-boot-xlnx 文件夹下看到 u-boot.elf 文件
Linux 内核编译
cd your_path/linux-xlnx # 进入Linux文件夹
export CROSS_COMPILE=~/tools/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- # 选择刚刚下载好的linaro工具链
export ARCH=arm # 选择编译的目标为arm平台
make xilinx_zynq_defconfig # 选择编译的配置是zynq
将之前使用 SDK 生成的 system-top.dts 文件拷入 your_path/linux-xlnx/arch/arm/boot/dts/ 中,pcw.dtsi 和 zynq-7000.dtsi 也一并拷入。
修改 dts 文件夹下的 Makefile 文件,在 ZYNQ 的配置列表中能找到一下片段,并作出修改
dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-cc108.dtb \
zynq-ebaz4205.dtb \
zynq-microzed.dtb \
zynq-parallella.dtb \
zynq-zc702.dtb \
zynq-zc706.dtb \
zynq-zc770-xm010.dtb \
zynq-zc770-xm011.dtb \
zynq-zc770-xm012.dtb \
zynq-zc770-xm013.dtb \
zynq-zed.dtb \
zynq-zturn.dtb \
zynq-zturn-v5.dtb \
zynq-zybo.dtb \
zynq-zybo-z7.dtb \
system-top.dtb <------新增这一行
回到 your_path/linux-xlnx 文件夹下,编译 dtb 和 zImage
make -j4 system-top.dtb # 编译dtb
能看到如下输出信息
DTC arch/arm/boot/dts/system-top.dtb
编译 zImage
make -j4 zImage
能看到如下输出信息
Kernel: arch/arm/boot/zImage is ready
第一次编译时可能会需要选一些配置选项,建议问一问 AI 如何选择。
根文件系统编译
本文选择使用 Buildroot 来编译根文件系统。安装 Buildroot 所需的依赖包
sudo apt-get update
sudo apt-get install build-essential libncurses-dev bison flex libssl-dev libelf-dev bc
创建工作目录
mkdir -p ~/buildroot_project
cd ~/buildroot_project
下载 Buildroot,建议下载一个稳定的 LTS 版本,例如 2023.02.x.
wget https://buildroot.org/downloads/buildroot-2023.02.10.tar.gz
tar -xvf buildroot-2023.02.10.tar.gz
cd buildroot-2023.02.10
打开图形化配置菜单,会看到一个蓝色的菜单界面。
make menuconfig
配置目标架构,进入 Target options,Target Architecture 选择 ARM(little endian),Target Architecture Variant 选择 cortex-A9,Targe ABI 选择 EABI.
配置工具链,进入 Toolchain,Toolchain type 选择 External Toolchain,Toolchain 选择 Custom Toolchain,Toolchain path 输入之前安装的 Linaro 工具链的路径 /home/username/tools/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf,Toolchain prefix 输入 arm-linux-gnueabihf. External toolchain gcc version 选择 7.x,External toolchain kernel headers series 选择 4.10.x,启用 C++ support,Toolchain has SSP support 启用。
进入 System configuration,System hostname 选择 ax7020(或任意其它命名),Root password 设置 root 用户的密码,Run a getty (login prompt) after boot 选择 TTY port,输入 ttyPS0(这是 Zynq 的串口)。
添加软件包,进入 Target packages,选择 Networking applications,启用 openssh,建议启用 tcpdump,可根据自己的需求添加不同的软件包。
配置完以上内容后,记得保存再退出。
开始编译
env -u LD_LIBRARY_PATH make -j4
根文件系统的编译时长会比较长,选的软件包越多编译时常也会越久,编译完成后可以在 ~/buildroot_fs/buildroot-2023.02.10/output/images 目录下看到 rootfs.tar,这就是编译好的根文件系统。
注:也可以使用默认 buildroot 自带的编译链,问题会少很多。
烧录 SD 卡
将一张 8GB 或以上的 Micro SD 卡插入 Ubuntu 电脑,电脑可能会自动挂载 SD 卡,可以使用 lsblk 命令查看 sd 卡的名称以及挂载在什么位置,可能会看到类似以下的输出
NAME SIZE TYPE MOUNTPOINT
sda 14.9G
├─sda1 256M /media/aaa/bootfs <-- 被挂载到了 /media/aaa/bootfs
└─sda2 14.6G /media/aaa/rootfs <-- 被挂载到了 /media/aaa/rootfs
手动卸载 sd 卡
sudo umount /dev/sda1
sudo umount /dev/sda2
再次运行 lsblk,能看到 sd 卡已经卸载
NAME SIZE TYPE MOUNTPOINT
sda 14.9G
├─sda1 256M
└─sda2 14.6G
使用 fdisk 工具进行分区和格式化
sudo fdisk /dev/sda
# (输入 o 创建一个空的 DOS 分区表)
# (输入 n 创建新分区, p, 1, 回车, +256M)
# (输入 a 设置为可启动)
# (输入 n 创建新分区, p, 2, 回车, 回车)
# (输入 w 保存并退出)
sudo mkfs.vfat -F 32 /dev/sda1
sudo mkfs.ext4 /dev/sda2
创建/mnt/bootfs 和/mnt/rootfs 并挂载 sd 卡
# 创建挂载点
sudo mkdir /mnt/bootfs
sudo mkdir /mnt/rootfs
# 挂载SD卡
sudo mount /dev/sda1 /mnt/bootfs
sudo mount /dev/sda2 /mnt/rootfs
在 SDK 中,使用之前生成的 FSBL.elf, system_top.bit, u-boot.elf,创建 BOOT.bin 文件,并将其拷贝到 /mnt/bootfs 目录下,还有 system-top.dtb 以及 zImage 一起拷贝到 /mnt/bootfs 目录下。
进入 rootfs.tar 的根目录,将其解压缩到 /mnt/rootfs 目录下
# 确保你在 Buildroot 的 output/images 目录下
cd ~/buildroot_fs/buildroot-2023.02.10/output/images
# 解压根文件系统到 SD 卡的第二个分区
sudo tar -xvf rootfs.tar -C /mnt/rootfs
全部文件复制完后就可以卸载 SD 卡了
sudo umount /mnt/bootfs
sudo umount /mnt/rootfs
这样 Linux 的 SD 启动卡就制作完成了。
启动 Linux
将黑金 7020 的跳线帽换到 SD 卡启动,连接上串口工具,Ubuntu 推荐 minicom,Windows 推荐 SerialForWindowsTerminal,上电就可以看到 uboot 的打印信息,uboot 会在启动时有倒计时,在此期间按任意键可以进入 uboot 界面,显示如下
Zynq>
进入 uboot 界面后,输入以下指令并保存到环境,配置 uboot 的启动参数并重启
# 设置一个名为 'bootargs' 的环境变量来存放内核命令行参数
setenv bootargs 'console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootwait'
# 设置完整的启动命令
setenv bootcmd 'mmc dev 0; fatload mmc 0 0x3000000 zImage; fatload mmc 0 0x2A00000 system-top.dtb; bootz 0x3000000 - 0x2A00000'
# 保存设置,防止重启后丢失
saveenv
# 重启
reset
看到以下打印说明 Linux 已经成功启动了,输入用户名和密码即可登录 Linux 系统。
ax7020 login: