为第三方ZYNQ开发板定制PYNQ镜像:从环境搭建到镜像烧录全流程解析
1. 为什么需要自己动手定制PYNQ镜像?
如果你手头有一块非官方的ZYNQ开发板,比如一些国产的或者小众厂商出的板子,想体验PYNQ那种用Python轻松玩转FPGA的爽快感,大概率会碰壁。去PYNQ官网一看,支持的板卡列表里就是没有你那一款。官方镜像不兼容,直接烧录要么根本启动不了,要么就是各种外设(比如网口、LED、按键)没法用,PYNQ的Overlay功能也就成了摆设。
这时候,自己动手为心爱的板子“量身定制”一个PYNQ镜像,就成了唯一的选择。听起来很高大上,像是芯片原厂工程师干的活,但其实整个过程就像照着菜谱做一道大菜,步骤清晰,材料明确,需要的更多是耐心和细心。我当初给自己的那块“三无”ZYNQ板卡(无官方PYNQ支持、无完整BSP、社区资料少)做镜像时,也是摸着石头过河,踩了不少坑。今天我就把这套从零开始,基于PYNQ v3.0.1和2022.1工具链的“保姆级”流程拆解给你看,目标是让你也能复现,把PYNQ跑在自己的板子上。
简单来说,定制镜像的核心就三步:搭好厨房(环境)、备好食材(硬件文件)、开火烹饪(编译烧录)。厨房就是我们的Ubuntu编译环境,食材就是描述你板子硬件电路的比特流(.bit)、硬件描述(.xsa, .hwh)等文件,烹饪则是利用PYNQ的框架把这些东西打包成一个可启动的SD卡镜像。整个过程虽然耗时(编译一次可能要好几个小时),但一旦成功,那种成就感是无与伦比的。接下来,我们就从零开始,一步步走进这个“厨房”。
2. 搭建编译环境:准备你的“厨房”
工欲善其事,必先利其器。编译PYNQ镜像需要一个“干净”且“强大”的Linux环境。强烈建议在虚拟机里操作,因为过程中会安装很多大型软件(比如几十个GB的Vitis),配置复杂的环境变量,万一搞乱了也不会影响你的主力机系统。
2.1 虚拟机与Ubuntu系统安装
首先,你需要一个虚拟机软件。VMware Workstation Pro现在对个人用户免费了,直接去官网下载安装就行。接着,去国内镜像站(比如中科大)下载Ubuntu 20.04.6 LTS的桌面版ISO镜像。为什么是20.04?因为PYNQ v3.0.1官方明确支持这个版本,与Vitis/Petalinux 2022.1的兼容性最好,能避开很多莫名其妙的依赖问题。
创建虚拟机时,有几个关键点要注意:
- 硬盘空间:至少分配400GB!这不是开玩笑。Vitis完整安装可能就要100多GB,Petalinux也要几十GB,编译过程中产生的中间文件以及最终的根文件系统也非常庞大。空间不足是编译失败最常见的原因之一。
- 内存和CPU:尽量多分配一些资源。建议内存不少于8GB(16GB更佳),处理器核心数给4个或以上,这能显著加快后续的编译速度。
- 系统设置:安装好Ubuntu后,第一件事是进入“设置”->“电源”,把“空白屏幕”和“自动挂起”都设为“从不”。防止编译到一半,系统自动休眠或锁屏,导致进程中断。
为了方便后续操作,我们还需要关闭sudo命令的密码验证。在终端里依次执行:
sudo su # 切换到root用户,需要输入当前用户密码 visudo # 编辑sudoers文件在文件末尾添加一行(请将your_username替换为你实际的用户名):
your_username ALL=(ALL) NOPASSWD: ALL保存退出。这样在后续漫长的编译过程中,脚本需要sudo权限时就不会再弹窗打断你了。
2.2 安装核心工具链:Git、PYNQ源码与QEMU
环境的基础是软件包。打开终端,首先更新软件源并安装Git:
sudo apt update sudo apt install git -y接着,克隆PYNQ的官方仓库,并切换到我们需要的v3.0.1版本分支:
git clone https://github.com/Xilinx/PYNQ.git cd PYNQ git checkout origin/image_v3.0.1这里有个小坑:PYNQ的编译脚本会用到QEMU(一个处理器模拟器)来做环境检查。老版本的脚本里,QEMU的下载链接可能已经失效。我们需要手动修复一下。用文本编辑器打开sdbuild/scripts/setup_host.sh文件,搜索http://wiki.qemu-project.org/download/qemu-$qemuver.tar.bz2这行,把它替换成:
https://download.qemu.org/qemu-$qemuver.tar.bz2保存后,先安装一个必要的库,然后运行环境配置脚本:
sudo apt-get install ncurses-dev -y ./sdbuild/scripts/setup_host.sh这个脚本会自动安装和配置一系列编译所需的工具(如QEMU、Crosstool-NG等)。运行完成后,它应该会在你的~/.profile文件末尾添加环境变量。你可以用cat ~/.profile查看末尾是否有类似PATH=/opt/qemu/bin:/opt/crosstool-ng/bin:$PATH的行。如果没有,就手动加上。最后,可以运行检查脚本验证环境:
./sdbuild/scripts/check_env.sh如果看到一堆“OK”和“Found”,说明基础厨房已经搭好了。
2.3 安装“重型厨具”:Petalinux与Vitis
这两者是Xilinx官方提供的“重型厨具”,体积巨大,安装过程也相对繁琐。
安装Petalinux 2022.1:
- 去AMD官网下载Petalinux 2022.1安装器。需要注册账号,填写信息时可能会遇到地域限制,这是一个常见的麻烦点。
- 下载后,假设安装包在
~/Downloads下,给予执行权限并安装:
安装过程是图形化的,按照提示操作即可。我建议安装到你的家目录下,比如cd ~/Downloads sudo chmod 755 petalinux-v2022.1-*-installer.run ./petalinux-v2022.1-*-installer.run/home/your_username/petalinux。 - 安装完成后,将Petalinux的环境变量加入shell配置。编辑
~/.bashrc文件,在末尾添加:
然后执行source ~/petalinux/settings.shsource ~/.bashrc使其生效。
安装Vitis 2022.1(包含Vivado):这是最耗时的步骤。强烈建议不要在虚拟机内部下载这个几十GB的安装包。最好在Windows宿主机上下载好,然后通过VMware的“共享文件夹”功能挂载到虚拟机里。
- 在AMD官网下载“Xilinx Unified Installer 2022.1: Linux Self Extracting Web Installer”或离线包。
- 在VMware设置中,将包含安装包的Windows目录设置为共享文件夹。
- 在Ubuntu虚拟机中,该共享文件夹通常位于
/mnt/hgfs/下。进入该目录,解压安装包:cd /mnt/hgfs/YourSharedFolder/ tar -zxvf Xilinx_Unified_2022.1_*.tar.gz - 在运行安装程序前,先安装一个库,避免安装界面卡住:
sudo apt install libtinfo5 -y - 进入解压后的目录,运行安装程序:
cd Xilinx_Unified_2022.1_* ./xsetup - 安装界面启动后,选择安装Vitis,在器件选择页面,务必只勾选你开发板对应的芯片系列(例如Zynq-7000或UltraScale+ MPSoC),这样可以节省大量磁盘空间和安装时间。其他步骤按默认选项进行即可。
- 安装完成后,同样需要添加环境变量。在
~/.bashrc末尾添加:
别忘了source /tools/Xilinx/Vitis/2022.1/settings64.shsource ~/.bashrc。最后,安装一个GTK模块,防止Vivado启动时报错:sudo apt install libcanberra-gtk-module -y
至此,我们所有的“厨具”和“灶台”都已就位。可以开始准备最重要的“食材”了——你的开发板硬件描述文件。
3. 准备硬件描述文件:收集“食材”
PYNQ镜像要能在你的板子上跑起来,内核必须知道你的硬件长什么样。这就需要我们提供一份“硬件说明书”,主要包括.bit(比特流)、.xsa(硬件描述存档)和.hwh(硬件描述头文件)三个核心文件。
3.1 理解文件结构
在PYNQ源码的boards目录下,官方为PYNQ-Z2等板子提供了参考。我们不需要那么复杂的结构,为自己板子准备的最小文件集如下:
你的板子名称(例如 my_zynq_board)/ ├── base/ │ ├── base.bit # FPGA配置比特流文件 │ ├── base.hwh # 硬件描述文件,用于PYNQ解析Overlay │ ├── base.py # 板级支持Python文件(可从官方板复制) │ └── base.xsa # Vivado导出的硬件描述存档 ├── petalinux_bsp/ │ └── hardware_project/ │ └── base.xsa # 与上面相同的.xsa文件,用于生成BSP └── 你的板子名称.spec # 板卡规格配置文件.spec文件是“食谱”,告诉编译系统如何为这块板子烹饪。它的内容很简单,但至关重要:
ARCH_my_zynq_board := arm # Zynq-7000用arm,MPSoC用aarch64 BSP_my_zynq_board := # 留空,我们用.xsa生成 BITSTREAM_my_zynq_board := base/base.bit FPGA_MANAGER_my_zynq_board := 1 # 设为1,上电自动加载比特流 STAGE4_PACKAGES_my_zynq_board := xrt pynq ethernet boot_leds注意:文件名(my_zynq_board.spec)和文件内的变量后缀(ARCH_my_zynq_board)必须与你创建的板子文件夹名称完全一致。
3.2 使用Vivado生成硬件文件
现在,打开Vivado,为你的板子创建一个最基础的硬件工程。
- 创建工程:启动Vivado,创建新工程,工程类型选择“RTL Project”,在添加源文件和约束文件的页面都直接跳过。
- 选择器件:最关键的一步,在“Default Part”页面,通过搜索准确选择你的开发板上的ZYNQ芯片型号。如果列表里有你的具体板卡型号更好,没有的话就选对芯片型号。
- 创建Block Design:在Flow Navigator中点击“Create Block Design”,命名为
system_ps。 - 添加并配置ZYNQ IP:在Diagram窗口中点击“+”号,搜索并添加“ZYNQ7 Processing System”IP(对于Zynq-7000)或“Zynq UltraScale+ MPSoC”IP(对于MPSoC)。
- 双击添加的IP核,进入配置界面。这里需要根据你板子的实际硬件连接来配置。这是整个流程中最需要硬件知识的一步。你需要参考开发板原理图或厂家提供的预设(Preset)来配置DDR型号、时钟、UART、SD卡、以太网等外设。如果厂家提供了XSA或Tcl配置文件,直接导入会省事很多。如果什么都没有,你就需要手动一项项核对。一个常见的启动最小配置至少需要:DDR控制器(型号和容量)、UART(用于串口调试)、SD卡控制器(用于启动)。
- 生成输出产品:配置完成后,在Source窗口中右键点击
system_ps.bd,选择“Generate Output Products”,综合一下。 - 创建HDL Wrapper:再次右键点击
system_ps.bd,选择“Create HDL Wrapper”,让Vivado生成顶层的HDL文件。 - 生成比特流:点击“Generate Bitstream”。这个过程会比较长,取决于设计复杂度。
- 导出硬件:比特流生成后,点击菜单栏“File” -> “Export” -> “Export Hardware”。在弹出窗口中,务必勾选“Include bitstream”,然后导出XSA文件。
导出的XSA文件包含了比特流和硬件描述信息。我们还需要从中提取出独立的.bit和.hwh文件。Vivado导出的XSA文件其实是一个压缩包。你可以用以下命令解压并获取所需文件(假设你的工程在~/vivado_projects/my_board):
# 在PYNQ源码的boards目录下,创建你的板子文件夹结构 cd PYNQ/boards mkdir -p my_zynq_board/base mkdir -p my_zynq_board/petalinux_bsp/hardware_project # 从Vivado工程目录复制文件 # 假设导出的XSA文件为 design_1_wrapper.xsa cp ~/vivado_projects/my_board/*.xsa ./my_zynq_board/base/ cp ~/vivado_projects/my_board/*.runs/impl_1/*.bit ./my_zynq_board/base/ # 比特流路径可能不同 # .hwh文件通常在同名.xsa解压后的目录里,或由Vivado在导出时生成更稳妥的方法是:在Vivado的“File” -> “Export” -> “Export Hardware”时,选择“Pre-synthesis”或“Pre-implementation”导出XSA,然后PYNQ的编译系统会自动从中生成.bit和.hwh。但为了确保无误,我习惯手动准备好。你可以从官方板(如Pynq-Z2)的base文件夹里复制一个base.py和.spec文件模板过来,然后按上文修改.spec文件,并将三个硬件文件重命名为base.bit,base.xsa,base.hwh。最后,别忘了把base.xsa再复制一份到petalinux_bsp/hardware_project/目录下。
4. 编译与优化:开始“烹饪”
食材备齐,可以开火了。但直接编译会非常慢,因为要从头编译整个Linux系统。PYNQ很贴心地提供了“半成品”——预编译的根文件系统和源码包。
4.1 获取预编译文件加速
前往PYNQ官网的下载页面,找到“PYNQ v3.0.1”相关部分,下载两个文件:
- PYNQ rootfs:根据你的芯片架构选择
aarch64或arm版本。 - Prebuilt PYNQ source distribution binary。
下载后,将它们放入PYNQ/sdbuild/prebuild/目录下,并分别重命名为:
pynq_rootfs.aarch64.tar.gz(或pynq_rootfs.arm.tar.gz)pynq_sdist.tar.gz
注意:有时官网下载的源码包后缀可能是.gz而不是.tar.gz。如果是这样,你需要手动解压后重新打包:
gunzip pynq_sdist.gz # 解压得到 pynq_sdist 文件 tar -cvf pynq_sdist.tar pynq_sdist # 打包为tar gzip pynq_sdist.tar # 压缩为.tar.gz mv pynq_sdist.tar.gz pynq_sdist.tar.gz # 确保文件名正确4.2 解决网络依赖问题
编译Petalinux部分时,需要下载一个叫sstate-cache的缓存包,体积很大且国内下载极慢甚至失败。我们可以预先下载好。
- 在AMD官网的Petalinux下载页面,找到2022.1版本的存档,下载
sstate-cache文件(选择对应架构)。 - 将其解压到Ubuntu虚拟机的一个目录,例如
/home/xilinx/sstate_aarch64。 - 在你的板子目录(如
my_zynq_board)下创建petalinux_bsp/meta-user/conf/目录。 - 在
conf目录下创建petalinuxbsp.conf文件,内容为:
这样编译时就会使用本地的缓存,速度飞快且稳定。SSTATE_DIR = "/home/xilinx/sstate_aarch64"
4.3 执行编译命令
一切就绪,进入PYNQ/sdbuild目录,执行编译命令:
make BOARDS=my_zynq_board PREBUILT=1这里的BOARDS参数指定你的板子文件夹名,PREBUILT=1告诉系统使用我们准备好的预编译文件。接下来就是漫长的等待,时间可能从1小时到数小时不等,取决于你的机器性能。编译过程会依次构建Bootloader、内核、设备树,安装PYNQ Python包等。如果一切顺利,你最终会在sdbuild/output/目录下看到生成的镜像文件:my_zynq_board-3.0.1.img。
5. 烧录与排坑:上桌“品尝”
得到镜像文件后,用读卡器将它烧录到SD卡(容量建议16GB或以上)。可以使用balenaEtcher或Win32 Disk Imager这类工具。将烧录好的SD卡插入开发板,设置启动模式为SD卡启动,连接串口线,上电。
5.1 首次启动与常见问题
理想情况下,你应该能在串口终端看到内核启动信息,最终进入Ubuntu系统的登录界面(用户名xilinx,密码xilinx)。但现实往往骨感,这里分享两个我踩过的大坑:
问题一:Kernel Panic - not syncing: VFS: Unable to mount root fs这是最令人头疼的错误之一,提示内核找不到根文件系统。除了常见的SD卡质量问题外,有两个硬件相关原因:
- SD卡写保护(WP)引脚问题:有些板子的SD卡槽硬件设计未使用写保护引脚,但Vivado配置中却使能了它。解决方法是在设备树中禁用WP。在你的板子目录下(如
my_zynq_board/petalinux_bsp),创建文件meta-user/recipes-bsp/device-tree/files/system-user.dtsi,加入以下内容(假设SD卡接在SD0):/include/ "system-conf.dtsi" / { }; &sdhci0 { status = "okay"; max-frequency = <50000000>; no-1-8-v; disable-wp; /* 关键:禁用写保护 */ } - SD卡与eMMC设备号映射错误:有些板子设计是eMMC接在SD0,SD卡槽接在SD1。但PYNQ默认从
mmcblk0p2(即SD0的第2分区)挂载根文件系统。这会导致系统尝试从eMMC启动。解决方法是在PYNQ源码中修改启动参数。找到sdbuild/boot/meta-pynq/recipes-bsp/device-tree/files/pynq_bootargs.dtsi文件,以及sdbuild/Makefile文件,将其中的root=/dev/mmcblk0p2全部替换为root=/dev/mmcblk1p2,然后重新编译。
问题二:网络无法连接如果系统能启动但无法上网,可能是以太网PHY芯片驱动问题。你需要确认Vivado中配置的以太网IP核型号与板载PHY芯片是否匹配,并在设备树中正确配置PHY的地址和兼容字符串。这需要查阅你的板子原理图和PHY芯片手册。
5.2 成功启动后的操作
当看到xilinx@my_zynq_board:~$这样的提示符时,恭喜你!你可以尝试运行sudo python3进入Python环境,然后from pynq import Overlay导入PYNQ库。如果成功,说明基础系统已就位。接下来,你可以把之前生成的base.bit和base.hwh文件拷贝到板子的/home/xilinx/pynq/overlays/base/目录下(可能需要先创建),然后在Jupyter Notebook中尝试加载你自己的Overlay,体验用Python控制FPGA的乐趣。
整个定制过程就像完成一个复杂的乐高项目,每一步都需要仔细对照说明书(文档和原理图)。失败是常态,尤其是第一次。但每解决一个报错,你对系统的理解就加深一层。当最终你的板子跑起PYNQ,所有外设正常工作那一刻,你会觉得之前所有的折腾都是值得的。这份指南希望能为你铺平道路,减少一些摸索的弯路。记住,耐心和查阅官方文档、社区Issue是你最好的工具。祝你一次成功!
