2. 开发环境搭建:工欲善其事,必先利其器

做嵌入式Linux开发,环境搭建是第一道坎。很多人觉得装个软件而已,能有多难?结果卡在版本兼容性上好几天。我刚开始搞Zynq那会儿,就吃过这个亏——Vivado和PetaLinux版本没对齐,编译到一半报错,查了半天才发现是工具链不匹配。

这一章,咱们把环境彻底搞定。从Vivado安装到NFS/TFTP服务器验证,每一步我都会把坑点指出来。

2.1 安装Vivado与PetaLinux

Vivado和PetaLinux的版本必须严格对应。举个例子,Vivado 2020.2必须搭配PetaLinux 2020.2,混用会出各种奇怪问题。

组件 推荐版本 说明
Vivado 2020.2 / 2021.1 包含Vivado HLx、Vitis、DocNav
PetaLinux 2020.2 / 2021.1 必须与Vivado版本一致
Ubuntu 18.04 / 20.04 推荐Ubuntu 20.04 LTS
注意:PetaLinux对Ubuntu版本有严格限制。Ubuntu 22.04及以上版本直接安装PetaLinux 2020.2会报依赖错误。我建议用Ubuntu 20.04,省心。

安装步骤其实不复杂,但有几个关键点:

  1. 下载安装包:从Xilinx官网下载Vivado和PetaLinux的tar包。文件很大,Vivado大约20GB,PetaLinux约10GB。
  2. 安装Vivado:运行xsetup,选择"Vivado HL WebPACK"或"Vivado HLx Edition"。我个人习惯全装,省得后面缺组件。
  3. 安装PetaLinux:解压后运行./petalinux-v2020.2-final-installer.run。安装路径不要有中文或空格。
  4. 设置环境变量:每次使用前都要source一下。
# 安装PetaLinux
mkdir -p ~/Xilinx/petalinux/2020.2
./petalinux-v2020.2-final-installer.run ~/Xilinx/petalinux/2020.2

# 设置环境变量(建议加到.bashrc里)
source ~/Xilinx/petalinux/2020.2/settings.sh
小技巧:把source命令加到~/.bashrc末尾,每次打开终端自动生效。但要注意,如果你同时装了多个版本,别冲突了。

2.2 配置交叉编译工具链

交叉编译,说白了就是在PC上编译出能在ARM上跑的程序。Zynq的CPU是ARM Cortex-A9,所以我们需要ARM交叉编译器。

PetaLinux安装完成后,自带了一套交叉编译工具链。路径一般在:

~/Xilinx/petalinux/2020.2/tools/linux-i386/gcc-arm-linux-gnueabi/bin/

但我不建议直接用这个。为什么?因为PetaLinux的工具链版本可能跟你的项目需求不匹配。我在项目中遇到过,用PetaLinux自带的工具链编译某个驱动模块,结果内核头文件版本对不上。

更好的做法是:

  1. 使用Linaro工具链:从linaro.org下载预编译的ARM交叉编译器。
  2. 设置环境变量:把工具链路径加到PATH里。
  3. 验证:运行arm-linux-gnueabihf-gcc --version。
# 下载Linaro工具链(以gcc-linaro-7.5.0为例)
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
tar -xf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
mv gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf ~/tools/

# 设置环境变量
export PATH=$PATH:~/tools/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm

# 验证
arm-linux-gnueabihf-gcc --version
核心概念:交叉编译的三个关键变量——CROSS_COMPILE指定编译器前缀,ARCH指定目标架构,PATH确保能找到工具链。这三个设对了,编译基本不会出路径问题。

2.3 搭建NFS与TFTP服务器

开发Zynq时,你不可能每次都把程序烧到SD卡里。太慢了。NFS和TFTP就是用来解决这个问题的。

  • TFTP:用于通过网络加载内核和设备树。启动时,U-Boot从TFTP服务器拉取文件。
  • NFS:用于挂载根文件系统。开发阶段,根文件系统放在PC上,Zynq通过网络访问。

说白了,TFTP管启动,NFS管运行。两者配合,开发效率翻倍。

2.3.1 安装与配置TFTP服务器

# 安装tftp-hpa
sudo apt-get install tftp-hpa tftpd-hpa

# 创建TFTP根目录
sudo mkdir -p /tftpboot
sudo chmod 777 /tftpboot

# 修改配置文件 /etc/default/tftpd-hpa
sudo vim /etc/default/tftpd-hpa

配置文件内容:

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
注意:-c选项允许创建文件,调试时很有用。但生产环境建议去掉。
# 重启服务
sudo systemctl restart tftpd-hpa
sudo systemctl enable tftpd-hpa

# 测试
echo "test" > /tftpboot/test.txt
tftp localhost
tftp> get test.txt
tftp> quit

2.3.2 安装与配置NFS服务器

# 安装nfs-kernel-server
sudo apt-get install nfs-kernel-server

# 创建NFS共享目录
sudo mkdir -p /srv/nfs/rootfs
sudo chmod 777 /srv/nfs/rootfs

# 修改配置文件 /etc/exports
sudo vim /etc/exports

在/etc/exports中添加:

/srv/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
安全提醒:no_root_squash允许客户端以root权限访问,开发时方便,但生产环境千万别这么配。我曾经在客户现场忘了改这个,被安全审计打了个低分。
# 重启服务
sudo exportfs -a
sudo systemctl restart nfs-kernel-server

# 测试(在本地挂载)
sudo mount -t nfs localhost:/srv/nfs/rootfs /mnt
ls /mnt
sudo umount /mnt

2.4 验证环境

环境搭好了,怎么知道能不能用?我一般做三个验证:

  1. 编译验证:写一个简单的Hello World,交叉编译后在Zynq上运行。
  2. TFTP验证:从Zynq的U-Boot里通过TFTP下载一个文件。
  3. NFS验证:在Zynq上挂载NFS共享目录。

2.4.1 交叉编译Hello World

// hello.c
#include <stdio.h>

int main() {
    printf("Hello from Zynq!\n");
    return 0;
}
# 交叉编译
arm-linux-gnueabihf-gcc -o hello hello.c

# 查看文件类型
file hello
# 输出: hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV)

看到"ARM, EABI5"就对了。如果显示的是x86,说明你用的是本地编译器。

2.4.2 TFTP下载测试

在Zynq的U-Boot命令行中:

# 设置IP地址(根据你的网络环境修改)
setenv ipaddr 192.168.1.100
setenv serverip 192.168.1.10

# 从TFTP下载文件
tftp 0x10000000 hello

# 验证
md 0x10000000 10

如果能看到数据,说明TFTP通了。

2.4.3 NFS挂载测试

在Zynq的Linux系统中:

# 挂载NFS
mount -t nfs -o nolock 192.168.1.10:/srv/nfs/rootfs /mnt

# 查看内容
ls /mnt

# 运行交叉编译的程序
/mnt/hello

如果看到"Hello from Zynq!",恭喜你,整个环境全部打通了。

验证总结:交叉编译能出ARM格式的二进制文件 → TFTP能下载文件到Zynq内存 → NFS能挂载并运行程序。这三步走通,开发环境就算彻底搭好了。
Zynq嵌入式Linux开发环境架构 开发主机(Ubuntu 20.04) Vivado(硬件设计) PetaLinux(系统构建) 交叉编译工具链 TFTP服务器 NFS服务器 网络 以太网 Zynq目标板 U-Boot(启动加载器) Linux内核 根文件系统(NFS挂载) 应用程序(交叉编译) TFTP用于启动阶段加载内核/设备树,NFS用于运行阶段挂载根文件系统

这张图把整个开发环境的关系理清楚了。左边是开发主机,右边是Zynq目标板,中间通过网络连接。开发流程就是:在主机上用Vivado做硬件设计,用PetaLinux构建系统,用交叉编译器编译应用,然后通过TFTP和NFS部署到目标板上。

环境搭建这一步,看起来琐碎,但值得花时间一次搞定。我见过太多人因为环境问题浪费好几天。按这个流程走,基本不会出大问题。如果遇到报错,先检查版本匹配,再检查网络配置,八成能解决。