1. 项目概述
在嵌入式Linux开发中,Xilinx Zynq-7000系列SoC因其ARM Cortex-A9双核处理器与可编程逻辑的完美结合而广受欢迎。本文将详细介绍基于Zynq-7020平台,使用PetaLinux工具链构建完整嵌入式Linux系统,并通过QSPI Flash和eMMC存储实现无SD卡启动的全流程。
传统Zynq开发常依赖SD卡作为启动介质,但在工业应用中,SD卡的物理可靠性和长期稳定性存在隐患。我们采用的方案将BOOT.BIN固化到QSPI Flash,系统镜像通过TFTP网络加载,最终部署到eMMC存储,既保证了启动可靠性,又兼顾了系统灵活性。
2. 开发环境准备
2.1 硬件配置要求
- 核心板:Xilinx ZC702评估板或兼容Zynq-7020核心板
- 调试工具:USB转UART调试线(连接UART0)
- 网络环境:千兆以太网连接(用于TFTP传输)
- 存储介质:板载QSPI Flash(至少16MB)、eMMC存储(建议4GB以上)
2.2 软件工具链
- Vivado 2021.1:生成硬件描述文件(XSA)
- PetaLinux 2021.1:构建Linux系统镜像
- TFTP服务器(如tftpd64):用于网络启动时的镜像传输
- 终端工具(如Putty或Minicom):用于串口调试
注意:Vivado和PetaLinux版本必须严格匹配,否则会导致兼容性问题。本文以2021.1版本为例,其他版本需调整相应命令参数。
3. PetaLinux系统构建流程
3.1 工程初始化
bash复制# 创建工程目录并导入XSA文件
mkdir -p ~/zynq7020_project && cd ~/zynq7020_project
cp <path_to_your_design>.xsa ./
# 设置PetaLinux环境变量
source /opt/pkg/petalinux/2021.1/settings.sh
# 创建Zynq类型工程
petalinux-create -t project --template zynq --name zynq7020_system
cd zynq7020_system
3.2 工程配置关键步骤
执行硬件描述导入和基础配置:
bash复制petalinux-config --get-hw-description ../
在配置界面中需要特别关注以下Yocto设置:
- 预构建文件路径:设置为本地缓存路径
code复制file:///home/uisrc/downloads_2021.1_update1 - 共享状态缓存:指向预构建的sstate-cache
code复制/home/uisrc/sstate_aaarch64_2021.1_update1/aarch64 - 禁用网络sstate源:取消勾选"Enable Network sstate feeds"
经验分享:本地缓存设置可显著减少构建时间。建议将PetaLinux安装包中的downloads和sstate_cache目录备份到本地,后续项目可重复利用。
3.3 设备树定制
编辑用户设备树文件:
bash复制vi project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
典型Zynq-7020设备树补充内容示例:
dts复制/ {
chosen {
bootargs = "console=ttyPS0,115200 earlycon clk_ignore_unused";
};
};
&gem0 {
status = "okay";
phy-mode = "rgmii-id";
phy-handle = <ðernet_phy>;
ethernet_phy: ethernet-phy@0 {
reg = <0>;
};
};
3.4 系统构建与镜像生成
执行完整构建过程:
bash复制petalinux-build
生成启动镜像:
bash复制petalinux-package --boot --u-boot --fpga --force
构建完成后,关键文件位于:
images/linux/BOOT.BIN:启动引导文件images/linux/image.ub:内核与根文件系统组合镜像images/linux/boot.scr:U-Boot脚本文件
4. 系统烧录与启动
4.1 QSPI Flash烧录
- 使用Vivado Hardware Manager连接开发板
- 将生成的BOOT.BIN烧录到QSPI Flash的0x00000000地址
- 配置开发板启动模式为QSPI启动
4.2 网络启动配置
在U-Boot命令行中配置网络参数:
bash复制setenv serverip 192.168.1.100 # TFTP服务器IP
setenv ipaddr 192.168.1.140 # 开发板IP
setenv netmask 255.255.255.0
setenv gatewayip 192.168.1.1
saveenv
通过TFTP加载系统镜像:
bash复制tftpboot 0x20000000 image.ub
bootm 0x20000000
遇到启动卡顿时,可尝试调整启动参数:
bash复制setenv bootargs console=ttyPS0,115200 earlycon clk_ignore_unused
bootm 0x20000000
5. eMMC系统部署
5.1 eMMC分区格式化
使用提供的自动化脚本对eMMC进行分区:
bash复制tftp -g -r emmc.sh 192.168.1.100
chmod +x emmc.sh
./emmc.sh /dev/mmcblk0
脚本执行后,eMMC将被划分为:
- 256MB FAT32分区(用于存放启动文件)
- 剩余空间为EXT4分区(用于根文件系统)
5.2 镜像写入eMMC
bash复制# 加载boot.scr和image.ub到内存
tftpboot 0x10000000 boot.scr
tftpboot 0x11000000 image.ub
# 写入eMMC第一分区
fatwrite mmc 0:1 0x10000000 boot.scr ${filesize}
fatwrite mmc 0:1 0x11000000 image.ub ${filesize}
# 验证写入内容
fatls mmc 0:1
5.3 配置eMMC自动启动
设置U-Boot环境变量:
bash复制setenv bootcmd 'fatload mmc 0:1 0x20000000 image.ub; bootm 0x20000000'
setenv bootdelay -3 # 禁用启动延迟
saveenv
reset
6. 应用开发与集成
6.1 应用打包进根文件系统
-
在工程目录创建应用配方:
bash复制cd project-spec/meta-user/recipes-apps cp -r app-template myapp -
编辑配方文件
myapp.bb:bitbake复制SUMMARY = "My Custom Application" LICENSE = "CLOSED" SRC_URI = "file://myapp.c \ file://Makefile \ " S = "${WORKDIR}" do_compile() { oe_runmake } do_install() { install -d ${D}${bindir} install -m 0755 myapp ${D}${bindir} } -
启用应用配置:
bash复制echo 'CONFIG_myapp' >> project-spec/meta-user/conf/user-rootfsconfig petalinux-config -c rootfs # 在user packages菜单中勾选myapp
6.2 独立应用开发环境
-
设置交叉编译环境:
bash复制source images/linux/sdk/environment-setup-cortexa9t2hf-neon-xilinx-linux-gnueabi -
典型Makefile示例:
makefile复制CC = arm-xilinx-linux-gnueabi-gcc CFLAGS = -Wall -O2 -mcpu=cortex-a9 -mfpu=neon LDFLAGS = -static TARGET = myapp SRCS = $(wildcard *.c) OBJS = $(SRCS:.c=.o) all: $(TARGET) $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) clean: rm -f $(TARGET) *.o -
自动化构建脚本:
bash复制#!/bin/bash make clean && make [ -f myapp ] && cp myapp /mnt/share/
7. 常见问题排查
7.1 启动问题
现象:U-Boot启动后卡住无输出
解决方案:
- 检查串口终端配置(波特率115200, 8N1)
- 确认bootargs参数正确:
bash复制
setenv bootargs console=ttyPS0,115200 earlycon - 检查时钟配置,添加
clk_ignore_unused参数
7.2 TFTP传输失败
现象:tftpboot命令超时
排查步骤:
- 确认开发板与TFTP服务器网络连通
bash复制
ping 192.168.1.100 - 检查服务器防火墙设置
- 确认文件权限:
bash复制chmod 644 /tftpboot/image.ub
7.3 eMMC写入错误
现象:fatwrite命令执行失败
处理方法:
- 确认eMMC分区已正确格式化
- 检查文件大小是否超过分区剩余空间
- 尝试重新挂载分区:
bash复制
umount /dev/mmcblk0p1 fatfsck /dev/mmcblk0p1
8. 性能优化技巧
- 内核裁剪:通过
petalinux-config -c kernel移除不需要的驱动模块 - 根文件系统优化:使用BusyBox替代完整版工具集
- 启动加速:
- 启用内核压缩(XZ或LZO)
- 配置U-Boot跳过延时:
setenv bootdelay 0
- 存储优化:
bash复制# 在eMMC的EXT4分区启用写入缓存 mount -o remount,commit=60 /dev/mmcblk0p2 /mnt
通过本文介绍的方法,开发者可以构建一个高度定制化、稳定可靠的Zynq-7020嵌入式Linux系统,完全摆脱对SD卡的依赖。这种方案特别适合需要长期运行、高可靠性的工业应用场景。