ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ZYNQ7020从零到Linux最小系统完整实战指南

ZYNQ7020从零到Linux最小系统完整实战指南 最近在折腾ZYNQ7020从一片空白到最后把Linux跑起来整个过程踩了不少坑。网上关于ZYNQ的资料虽然多但大多是零散的知识点真正能照着从零走到系统启动的完整流程其实不多。这篇博文就是想把我的实操过程完整记录下来——用Vivado搭硬件工程用Vitis写软件并生成启动镜像最后在板子上把Linux最小系统跑起来。涉及的核心关键词也很明确ZYNQ7020、Linux、Vivado、Vitis、最小系统。这套流程最适合两类人一是刚拿到ZYNQ开发板、想快速验证平台可用性的新手二是做过单片机但没接触过异构SoC的嵌入式工程师。前者可以照着步骤完整复现一遍后者可以重点看我写的报错排查部分——很多坑都是文档里查不到的。整个过程不需要写太多代码核心是理解PS处理系统和PL可编程逻辑是怎么配合的以及Linux系统在ZYNQ上是如何一步步启动起来的。1. ZYNQ7020的架构认知与最小系统设计思路1.1 为什么要用ZYNQ7020做Linux开发ZYNQ7020本质上是一颗异构SoC它把双核Cortex-A9处理器PS端和Xilinx 7系列FPGA逻辑PL端封装在同一个芯片里。这颗片子之所以在嵌入式领域这么流行核心原因是它的灵活性PS端能跑完整的Linux操作系统PL端能实现高速并行逻辑和自定义外设两者通过AXI总线高速互联。从Linux最小系统的角度来说ZYNQ7020的定位其实和树莓派类似但它强在PS端与PL端的协同工作能力。跑Linux只需要用到PS端的基本外设所以哪怕你完全不动PL逻辑ZYNQ7020也能像一颗高性能ARM芯片那样工作。对于想学习嵌入式Linux的人ZYNQ7020是一个很好的载体——它不会像树莓派那样全是封装好的黑盒子启动流程中的每个环节你都可以用硬件工具去观察和调试。1.2 最小系统的组成拆解搭建Linux最小系统本质上要做三件事硬件工程、软件工程、启动镜像。硬件工程决定PS端以什么频率跑、DDR怎么初始化、UART和SD卡用哪个接口软件工程生成FSBLFirst Stage Boot Loader和后续的应用程序启动镜像则把前面所有东西打包成BOOT.BIN文件让芯片上电后能按顺序启动。另一个关键认知是Linux最小系统并不等于一个精简版的发行版而是由三部分组成的启动集合——U-Boot引导程序、Linux内核镜像、根文件系统。U-Boot负责初始化DDR并加载内核内核负责挂载根文件系统和驱动各类外设根文件系统则提供最基础的shell环境和命令工具。三者缺一不可任何一环出问题都会导致启动失败这也是很多新手最头疼的地方。1.3 板卡和工具链的准备在开始之前需要准备好以下材料和环境一块ZYNQ7020开发板我用的是Xilinx官方的ZCU开发板型号做了适配市面上大多数国产7020开发板操作流程是一样的、一张FAT32格式化的SD卡、一根USB转UART的调试串口线、以及安装好的Vivado和Vitis工具链。这里特别提醒一下工具版本的选择直接决定你的开发体验。我使用的是Vivado 2020.2和配套的Vitis这两者版本必须匹配否则后期导出xsa文件的时候会出现莫名其妙的兼容性问题。安装时建议勾选全部组件尤其是Vitis需要的SDK相关组件缺了它们后面创建platform工程时会失败。环境准备好之后就可以开始真正的实战了。2. 硬件工程设计从创建工程到导出xsa2.1 创建Vivado工程并选择器件打开Vivado在Quick Start界面选择“Create Project”然后按向导一步步操作。工程名建议用简洁的英文名称比如“zynq_linux”路径不要包含中文和空格。在Project Type这一步选择“RTL Project”并勾选“Do not specify source files at this time”这样可以直接在Block Design中拖拽配置。器件型号选择环节需要特别留意对于ZYNQ7020封装不同但核心逻辑相同的型号有很多种比如XC7Z020CLG400、XC7Z020CLG484等。选择时必须和你手里的板子完全一致否则生成的bitstream烧录到板子上会失败严重时还会出现下载时识别不到芯片的情况。如果不知道板子上用的是哪个具体型号可以从板卡配套的原理图或者官方资料中找到一般都会明确标注。2.2 Block Design中的PS配置创建完成后点击“Create Block Design”给设计起名后就会进入IP Integrator界面。点击页面中间的“ Add IP”按钮搜索“ZYNQ7 Processing System”并添加这就是PS端的核心IP。双击打开ZYNQ7 Processing System的配置界面能看到一列非常多的配置选项但是对我们搭建最小系统来说只需要关注三个模块。首先是DDR配置ZYNQ7020支持多种DDR型号你需要根据板卡上实际焊接的DDR颗粒来选择对应的配置不同板卡有不同型号选错了DDR配置会导致启动时内存初始化失败系统卡死在重启循环里。其次是UART配置默认的UART1在MIO 14和MIO 15上一般不建议修改因为这是板上串口调试的标准引脚。最后是SD卡配置选择SD 0或SD 1取决于板卡原理图上SDIO接口连接到了哪个bank的MIO引脚上。2.3 配置DDR参数的重要性DDR配置是整个PS初始化最关键的一步但也是很多新手最容易忽略的一步。ZYNQ7020的PS端DDR控制器是一个复杂的初始化状态机上电后它需要按照DDR颗粒的时序规范完成训练过程。如果你选择了一个和板上实际颗粒不匹配的型号最典型的症状就是UART完全没有输出或者启动后反复重启。我自己在调试时就吃过这个亏直到最后板子点不亮回查原理图才知道板载DDR型号和我在配置界面里选择的不一致。这里给大家一个实用建议配置DDR时先去板卡供应商的网站查一下对应的Vivado工程示例直接对照抄配置是最稳妥的。如果是自研板则需要阅读DDR颗粒的datasheet确保容量、速率、位宽都能对上。2.4 添加最小PL逻辑并生成bitstreamPS端配置好之后作为最小系统其实可以不需要任何PL逻辑。但是为了验证PL通路是否正常也为了后面方便扩展自定义外设我养成了一个习惯——在Block Design里加上一个简单的GPIO模块。点击“Add IP”搜索“AXI GPIO”然后点击“Run Connection Automation”让Vivado自动完成AXI互联总线、复位和时钟的连接这样省力了很多。连接完成后回到Block Design窗口能看到整个系统的互联情况。接下来按 F6 键先验证一下设计再在Sources窗口右键选中设计文件选择“Generate Output Products”等待综合完成。最后点击左边工具栏的“Generate Bitstream”Vivado会依次完成综合、布局布线和bit文件生成这个过程在配置一般的电脑上可能需要十几分钟不要中途中断。2.5 导出硬件平台文件xsabitstream生成成功后需要把硬件工程导出给Vitis使用。执行菜单栏“File” - “Export Hardware”弹窗中记得勾选“Include bitstream”这样导出的xsa文件就会包含PL端的配置信息。xsaXilinx Support Archive文件是Vivado和Vitis之间的桥梁里面包含了PS端配置、PL端bitstream、地址映射表等所有关键信息。拿到xsa文件后硬件设计部分就算完成了。这里分享一个很重要的经验xsa文件导出后不要再修改Block Design里的任何配置如果确实改了需要重新生成bitstream并再次导出xsa。否则你在Vitis里建立的software platform工程会和你实际的硬件不一致轻则SDK无法启动重则下载调试时找不到匹配的器件。3. Vitis软件平台与启动镜像制作3.1 创建Vitis工作空间并导入xsa打开Vitis第一次启动时会让你选择工作空间路径建议在工程目录下新建一个“vitis_workspace”文件夹和Vivado工程分开存放避免文件混在一起后找不到。进入主界面后选择“File” - “New” - “Platform Project”输入工程名后点击“Next”。在Platform Project向导里点击“Browse”找到上一步导出的xsa文件选定后Vitis会自动识别硬件平台信息并提示创建平台所需的组件。这里有个细节需要注意Vitis版本和xsa的生成版本必须一致如果Vitis版本比Vivado版本低导入xsa会直接报错如果版本高部分老版本的配置可能无法识别。最稳妥的做法是使用同一年版本的Vivado和Vitis安装包。3.2 理解platform、FSBL与应用工程的关系Platform工程生成后Vitis会自动构建一个完整的软件平台里面包含了板级支持包、驱动库和FSBL源码。FSBL的全称是First Stage Boot Loader它负责芯片上电后的第一阶段初始化配置DDR、初始化UART然后根据启动模式跳转加载后续的引导程序。很多初次接触ZYNQ的朋友会把FSBL理解成U-Boot其实两者层级完全不同。FSBL固化在BootROM中是由Vitis生成的U-Boot是Linux启动的第二阶段引导程序两者是先后关系。FSBL通过BootROM跳转执行完成后会去读取启动设备中的U-Boot镜像并加载到DDR中再把控制权交给U-Boot。理解了这一层关系后面分析启动日志时就能很快定位问题出在哪一步。3.3 生成启动镜像BOOT.BIN平台工程构建完成后接下来要做的就是生成BOOT.BIN。但在此之前先要准备好U-Boot镜像、Linux内核镜像和根文件系统因为BOOT.BIN本质上就是把FSBL、bitstream和U-Boot这几部分打包在一起的容器。对于ZYNQ7020最常用的U-Boot和内核有两种获取途径一种是从芯片厂商官方提供的Linux发行包中获取另一种是从社区维护的代码仓库自行编译。对于最小系统来说官方发行包已经编译好的镜像文件完全够用不用折腾交叉编译环境。把官方包中提供的u-boot.elf、uImage、rootfs压缩包拷贝到一个临时目录备用。回到Vitis选择“Xilinx” - “Create Boot Image”在弹窗中按顺序添加三部分内容第一部分是FSBL文件选择平台工程中编译生成的fsbl.elf第二部分是bitstream文件从Vivado导出目录中找第三部分是U-Boot文件选取u-boot.elf。输出文件命名为BOOT.BIN路径选到SD卡的启动分区即可。3.4 SD卡分区与镜像烧录制作好BOOT.BIN之后还要把内核镜像和根文件系统放到SD卡上。这里推荐一个SD卡分区方案SD卡分成两个分区第一个分区格式化为FAT32容量建议512MB以上用来存放BOOT.BIN、uImage、boot.scr启动脚本第二个分区格式化为ext4用来存放根文件系统。Linux系统下用fdisk或gparted都能完成分区操作Windows下可以用DiskGenius。分区完成后把BOOT.BIN和uImage拷贝到FAT32分区然后把根文件系统压缩包解压到ext4分区。在Windows环境下读取ext4分区需要借助第三方软件比如Ext2Read或WSL。如果你觉得麻烦也可以在Linux主机或虚拟机里完成SD卡烧录操作。注意板上Linux启动默认从第一个分区读取BOOT.BIN所以这个文件一定要放在FAT32分区的根目录否则你会在串口终端看到BootROM反复报错。3.5 串口连接与启动观察把SD卡插入开发板用USB转UART线把板子的UART接口连上电脑。打开串口终端软件我用的是MobaXterm免费的Minicom也很好用波特率设置为115200数据位8位停止位1位无校验。确认连接正常后上电通过串口终端观察启动过程。预期看到的日志顺序大致是最先出现BootROM和FSBL的初始化信息然后U-Boot的logo和倒计时接着U-Boot加载uImage并启动内核最后内核挂载根文件系统并执行init进程。如果一切顺利最后你会看到shell提示符一台基于ZYNQ7020的Linux最小系统就算正式跑起来了。4. Linux最小系统的验证与常用命令配置4.1 网络、用户与开发环境的初始化系统起来之后第一件事是在shell里检查网络接口。多数ZYNQ开发板的PS端会引出GEM以太网接口U-Boot会通过设备树将网络设备暴露给内核。输入ifconfig -a查看网口名称和IP信息如果没分配IP可以用udhcpc命令获取动态地址。确保网络通畅之后后续的软件包下载和交叉编译部署都会方便很多。接下来是新建一个普通用户。这个习惯建议从第一天就养成因为root权限虽然方便但在开发调试时误操作的风险也高。输入useradd -m -s /bin/bash user1创建一个新用户然后passwd user1设置密码。之后切换到这个用户开始开发调试权限控制会清晰很多。配置环境变量时最常用的是PATH变量把常用工具目录加进去比如/bin和/usr/local/bin。4.2 烧写后常用Linux命令清单运行最小系统时由于没有图形界面你几乎所有的操作都依赖命令行。下面这张清单是我在实际开发中反复使用的命令很适合刚上手嵌入式Linux的朋友照着练习功能命令示例说明文件管理ls、cd、cp、mv、rm日常文件操作的基础命令查看系统信息cat /proc/cpuinfo、free -m查看CPU和内存使用情况系统启动管理dmesg、top、ps排查启动日志和运行状态网络配置ifconfig、ping、udhcpc配置和诊断网络连接设备管理cat /proc/mtd、ls /dev查看Flash和硬件设备节点内核模块insmod、rmmod、lsmod动态加载内核模块这些命令看着基础但实际开发中几乎每天都在用。我特别建议重点掌握dmesg和mount因为内核驱动初始化是否成功、外部存储设备是否挂载都靠这两条命令来观察。如果dmesg中有Error级别的输出通常意味着驱动或设备树配置有问题。4.3 根文件系统的裁剪思路最小系统里的根文件系统一般都不大几十MB就够用。裁剪时优先考虑BusyBox它是一个精简的Linux工具箱把ls、sh、mount等常用命令集成到一个二进制文件中体积小、移植方便非常适合资源受限的嵌入式场景。ZYNQ7020的官方Linux发行包中通常也集成了BusyBox可以直接作为最小系统的shell环境。如果后续需要做更复杂的应用可以考虑在SD卡上挂载更大的分区把交叉编译好的应用程序放到这里通过mount命令在运行时挂载到系统目录中。这种做法的好处是系统镜像保持精简应用升级时只需替换分区内容不需要重新烧写整个系统。5. Vitis下载调试识别不了芯片的核心排查方法5.1 硬件层面的排查清单热搜词里反复出现“vitis 下载调试的时候不识别芯片”这确实是ZYNQ开发中最常见的报错之一。先不要急着怀疑工具按顺序排查硬件因素。第一步是检查JTAG链路是否正常确保下载器的JTAG线缆连接到板载JTAG接口的TMS、TCK、TDI、TDO四个信号部分板子还需要连接地线。第二步是确认开发板供电足够ZYNQ7020在调试时PL和PS同时工作电流需求会明显增大如果电源线过细或稳压电流不够JTAG信号会出现偶发掉链子的现象。第三步是检查下载器本身Xilinx官方推荐的下载器是Digilent JTAG-HS3但很多国产下载器也能兼容。需要注意的是个别下载器需要在Vivado Hardware Manager里手动选择设备型号如果自动识别失败可以试着手动指定xc7z020。如果以上都排除仍然报错换一根短一点的USB线往往会有奇效——调试器对线材质量特别敏感长线或者劣质线缆都可能导致时序不稳定。5.2 软件层面的排查方法硬件没问题后软件设置是另一个高发区。首先确认硬件目标连接选择正确在Vitis的Debug Configuration里Target Setup必须指定到正确的硬件服务器和器件默认设置有时会沿用过时的连接信息导致探测失败。其次检查Vivado和Vitis的版本配套混用不同版本是最常见的人为原因xsa文件虽然能导入但底层调试驱动不一致会导致芯片无法识别。还有一个容易被忽视的点关闭其他正占用JTAG接口的程序。有些后台程序一直占用着调试器的驱动句柄这会导致Vitis无法访问硬件目标。打开设备管理器把其他可能占用USB端口的调试软件先退出然后重启Vitis再试一次。实测下来大多数“不识别芯片”的问题都能通过这一波组合拳解决。5.3 常见下载调试问题速查表故障现象可能原因解决方案识别不到芯片JTAG连接不良或电源不稳重插JTAG线检查开发板供电识别到芯片但编程失败版本不匹配或驱动占用统一工具链版本退出其他调试软件下载后系统不启动BOOT.BIN缺失或分区错误确认BOOT.BIN在FAT32分区根目录启动日志停在FSBLDDR配置与实际颗粒不符核对DDR型号配置U-Boot加载内核失败uImage路径或文件名错误检查启动脚本中的文件名和路径这张表里的每个场景都是我在实际调试中碰到过的尤其是DDR配置错误导致的FSBL卡住几乎可以说是新手必经之路。我建议遇到问题时先对照表格判断故障发生在启动的哪一个阶段再对症下药比盲目重刷镜像高效得多。5.4 Vivado常见报错的应对经验热搜词里还有好几个高频率出现的Vivado报错这里一并说下我的处理经验。第一个是“Vivado安装驱动无法识别板子”Windows系统下安装Vivado时驱动安装步骤很容易被安全软件拦截导致USB-JTAG下载器无法识别。解决办法是右键点击安装包选择以管理员身份运行安装驱动前临时退出安全软件。第二个是“vivado implement design变红”这个通常是因为时序约束不满足。实战中不要急着改约束文件先在“Report Timing Summary”里看具体的时序路径确认是哪条路径违例。对于最小系统来说AXI总线频率不高一般不会有严重的时序收敛问题变红更多是因为约束文件缺失或时钟定义错误。第三个是“vivado winpcap安装失败”WinPcap是Vivado装完后的可选组件主要用于仿真时的网络协议分析。这个组件即使没装成功也不影响硬件工程和下载调试可以忽略。但如果后续用到Vivado的以太网调试功能可以单独下载WinPcap或Npcap安装注意版本兼容性。6. 从最小系统到完整开发环境的扩展实践6.1 在内核中动态加载模块的方法最小系统跑通后下一步通常是驱动开发。ZYNQ7020的Linux内核是模块化设计的很多驱动并不需要编译进内核而是以.ko文件的形式动态加载。编写好驱动程序后用交叉编译器生成.ko文件然后用insmod命令手动加载再用lsmod确认模块是否被正确装载。模块加载不成功时先用dmesg查看内核日志。最常见的问题是模块编译时使用内核源码版本和当前运行的内核版本不一致导致module version mismatch。这里强烈建议在开发主机上交叉编译时指定与目标板完全一致的内核源码目录避免版本漂移带来的各种奇怪问题。6.2 利用PL端自定义外设扩展功能ZYNQ平台最大的价值在于PL端可以灵活扩展外设。以我的实战为例最小系统跑通后我在PL端添加了一个自定义的AXI GPIO模块用来控制板上的LED灯。在Vivado里修改Block Design添加AXI GPIO并连接到PS端重新综合生成bitstream再导出新的xsa。回到Vitis更新platform和Boot Image烧录后Linux里就能看到对应的设备节点操作LED只需要echo命令写入数值这种从硬件到软件全链路打通的感觉很有成就感。这里也给大家一个建议初期不要设计太复杂的PL逻辑从几个GPIO开始跑通数据通路以后再去折腾DMA、PCIe这类复杂接口。因为PL端的调试往往要同时排查硬件和软件复杂度呈指数级上升循序渐进会更稳妥。6.3 多分区与系统备份的实用技巧调试过程中SD卡里的系统会被反复刷写这就需要一个可靠的备份策略。我在实测中最常用的方案是使用dd命令将整个SD卡做成镜像备份存储到开发主机的磁盘上。一旦系统被玩坏插入备份卡就能秒回退到之前的状态节省大把时间。这个技巧在调试内核或驱动时特别实用。内核panic了、文件系统损坏了、环境变量被改乱了以前可能需要重新走一遍刷机流程现在有了完整镜像备份直接恢复等于重新插了一张卡。备份文件体积比较大建议存放到移动硬盘或NAS上避免占用工作机的主磁盘空间。6.4 ZYNQ7020后续的学习路径建议到这里ZYNQ7020的Linux最小系统已经完整跑通趁热打铁给出一条后续学习路径。第一个阶段是围绕PS端做Linux应用开发学会使用串口、网络、GPIO等基础外设熟悉设备树和内核模块的编写。第二个阶段是进入PL逻辑设计理解AXI总线协议学会自己封装IP核实现简单的自定义外设。第三个阶段是让PS和PL协同工作利用DMA实现高速数据搬运用FPGA做硬件加速体验异构计算的能力。每个阶段之间是层层递进的基础打不牢后面很容易陷入“代码能编译但硬件跑不通”的困境。就我个人的实操经验来看最快的学习路径是把官方例程源码一行一行读懂、改参数、重新编译、下载验证这个过程重复十遍以上你对ZYNQ平台的理解会有一个质的飞跃。最后分享一个我踩过多次坑之后的习惯每次做大的改动前先在Vivado里跑一遍完整的Bitstream生成再回到Vitis更新平台并下载每一个环节都确认无误后再继续下一步。很多莫名其妙的板级问题最后追查下来都是因为某一步的产物没刷新导致软件加载的还是旧的硬件配置。慢就是快这个道理在嵌入式开发里从来不会过时。
返回列表