
我一直觉得ZYNQ 和纯 FPGA 的学习路径完全是两码事。很多人一上来就抱着《Xilinx FPGA 权威设计指南》啃结果连 ZYNQ 的启动流程都没搞明白就被 boot.bin、image.ub 这些概念劝退了。这篇内容我不打算写成一本正经的教程而是结合我自己从纯 FPGA 跳到 ZYNQ 之后踩过的坑、捋清楚的逻辑把学习路线、PetaLinux 2025.1 制作 SD 启动卡的完整链路、以及从数码管到 MIPI/PCIe 这类外设接口的进阶顺序一次讲透。适合那种已经会点 Verilog、但被 ZYNQ 的 ARM 侧搞到头大的朋友也适合刚入门 FPGA 想找方向的新手。1. 先想清楚ZYNQ 和纯 FPGA 的学习逻辑根本不一样1.1 为什么很多人学 ZYNQ 时卡死在启动阶段我见过太多人把 ZYNQ 当成带 ARM 的 FPGA来学然后天天跟 FSBL、U-Boot、设备树较劲最后心态崩了。你仔细想一下ZYNQ 的难点不在于 FPGA 逻辑部分而在于它是一个异构 SoCPL可编程逻辑和 PS处理系统之间要通过 AXI 总线交互启动时要先由片上 BootROM 引导 FSBL再由 FSBL 初始化 DDR 并加载 U-Boot最后 U-Boot 把内核和设备树读进来。这个链路里每一步都有专门的工具和文件格式跟纯 FPGA 只要生成一个 bit 流就完事完全不同。很多人卡住本质上是没建立起ZYNQ 启动是一个多级引导过程的心智模型。你只有把这个模型刻在脑子里再去碰 PetaLinux才不会被各种报错带偏。说实话就算你暂时不打算跑 Linux只想用 ZYNQ 做裸机开发你也绕不开 FSBL 和 boot.bin。所以我的建议是学习 ZYNQ 的第一课不是写 PL 逻辑而是搞懂启动流程。这也是我踩了无数坑之后最大的感悟。1.2 从 FPGA 基础到 ARMFPGA 异构学习路线怎么规划如果你的目标是 ZYNQ我推荐的顺序是先打 FPGA 基础再涉足 PS 侧。第一步是 Verilog 语法和时序概念这里我不推荐一上来就抱着大部头啃直接用 Vivado 跑几个小工程效率最高。第二步是掌握常见的接口协议——UART、SPI、IIC、PWM这些足以覆盖大多数入门项目。第三步才是把视线转向 ZYNQ 的 PS 侧先学裸机下的 GPIO、UART、DDR 读写再进阶到 PetaLinux。当然这是我的路径不一定适合所有人但有一点是通用的你不需要把 FPGA 所有知识学完才去碰 ZYNQ。很多人在第一步就陷进去了觉得 DMA、高速串行接口、时序收敛没学透就不敢往下走。实际上ZYNQ 的 PL 侧完全可以后期在实际项目中逐步补齐ARM 核的存在本来就是为了帮你分担复杂逻辑的。1.3 开发环境选型Vivado、Vitis、PetaLinux 各管哪一段不少新手会混淆这三个工具的分工甚至有人问要不要三个都装。我的理解是这样的Vivado 负责 PL 侧也就是 RTL 设计、仿真、综合、布局布线它产出的是硬件描述文件XSAVitis 负责 PS 侧的软件和裸机应用开发也可以把它理解为传统嵌入式开发里的 IDE但它要依赖 Vivado 生成的硬件平台文件。PetaLinux 则是专门用来构建、定制和生成 Linux 系统镜像的工具它面向的是 FPGA 上的 Linux 开发场景。打个比方Vivado 是画图纸的Vitis 是在图纸上装门窗的PetaLinux 是装修整栋楼的。你要跑 Linux 系统就得三件套配合使用。而且这三个工具对版本非常敏感——比如 PetaLinux 2025.1 就要求对应的 Vivado 2025.1配错版本直接让你在工程导入阶段就抓瞎。所以装环境的第一步先把版本对应关系确认好。2. 搭建 PetaLinux 2025.1 工作环境版本、依赖与隐藏坑2.1 安装前的系统准备别再用 Ubuntu 18.04 硬扛了PetaLinux 2025.1 官方推荐 Ubuntu 22.04 或 24.04 LTS。我最早用的时候是在 Ubuntu 20.04 上装的结果安装脚本能跑完但构建时频繁报错后来换到 22.04 才清净。另外磁盘空间建议至少给 100GB因为这个工具链动辄下载好几个 GB 的依赖加上工程构建时产生的临时文件空间小了后期非常痛苦。还有一个几乎没人提的细节PetaLinux 要求非 root 用户安装而且安装路径里不能有空格或中文。有些同学喜欢把工具放在/home/用户名/my tools这种路径下后面跑petalinux-create时会遇到莫名其妙的路径解析问题。用/opt/pkg/petalinux这种纯英文无空格的路径能帮你省掉后面一堆麻烦。2.2 工程创建从 Vivado 导出 XSA 到 PetaLinux 导入的正确姿势拿到 Vivado 生成的 XSA 文件之后在 PetaLinux 里创建工程的命令并不复杂petalinux-create -t project -n my_zynq --template zynq petalinux-config --get-hw-description/path/to/xsa但这里有个非常多见的坑XSA 文件必须包含 bit 流信息。很多人在 Vivado 里做完 PL 设计后直接 Export Hardware结果忘了勾选 Include bitstream 选项。这样导入 PetaLinux 后PL 侧的逻辑没有被包进启动镜像硬件上电后 FPGA 部分是空的。正确的做法是在 Vivado 里先完成综合和实现生成 bit 流再用File - Export Hardware确保勾选 Include bitstream。另外petalinux-config打开的是图形化配置界面很多人第一次进去不知道该改什么。我通常在 Subsystem AUTO Hardware Settings 里确认一下串口配置是否跟板卡一致然后在 Image Packaging Configuration 里检查 rootfs 类型其他地方保持默认足够跑起一个最小的 Linux 系统了。2.3 构建时最常见的三个报错及对策先说第一个构建时提示缺少ip命令或tftp相关组件。这是依赖没装全的典型表现用以下命令补齐即可sudo apt install iproute2 tftpd-hpa libncurses5-dev libncursesw5-dev第二个报错是ERROR: No licensed Vivado installations found。这个多半是环境变量没配对PetaLinux 需要找到 Vivado 的安装路径。在运行任何 petalinux 命令之前先 source 一下 Vivado 的环境脚本source /opt/Xilinx/Vivado/2025.1/settings64.sh source /opt/pkg/petalinux/settings.sh第三个报错是构建 rootfs 时下载软件包失败。PetaLinux 的 rootfs 构建过程需要从网上下载一些包网络不稳定就会出现各种 fetch 失败。解决办法一是配置代理二是给 Yocto 设置本地缓存三是把 rootfs 类型改成initramfs这类不需要额外下载过多包的模式。从工程长期维护的角度我更建议配置一个稳定的网络环境因为 rootfs 的定制化往往才是 PetaLinux 真正花时间的地方。3. 生成 boot.bin、boot.scr、image.ub 三件套这次把每个文件的来龙去脉讲清楚3.1 为什么启动镜像要拆成三个文件而不是一个很多人第一次接触到 boot.bin、boot.scr、image.ub 时都会问为什么不能像普通嵌入式 Linux 那样搞一个 zImage 或者 uImage 就完事答案在于 ZYNQ 的启动过程是分阶段的每个阶段只负责一个任务。BootROM 上电后自动执行它不认识 FAT32也看不懂内核镜像它只知道去读启动设备里特定位置的 BOOT.BIN。把 FSBL、U-Boot、PL 的 bit 流打包成一个 boot.bin是为了让 BootROM 能用一个统一格式的文件完成最初的加载。U-Boot 起来之后它会去读取 boot.scr——这个文件本质上是一段 U-Boot 脚本告诉 U-Boot 内核镜像和设备树在哪、以什么参数启动。最后 U-Boot 根据这段脚本加载 image.ub。image.ub 是把内核、设备树、ramdisk 打包在一起的 FIT 镜像。拆成三段的好处是你可以单独更新内核而不用重烧整个启动介质这在产品迭代时特别有用。3.2 petalinux-package --boot 的完整调用逻辑PetaLinux 里生成 boot.bin 的方式很直接petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --fpga ./images/linux/bitstream.bit --u-boot这条命令的逻辑是把 FSBL、PL bit 流、U-Boot 的 ELF 文件打包成 BOOT.BIN。很多人好奇为什么不是直接用 FSBL 的源码去编译而是用 images/linux 目录下生成的现成 ELF。其实petalinux-build已经帮你把 FSBL 编译好了你不需要手动去碰源码只要确保硬件描述文件里的 bit 流信息完整即可。如果你需要自定义 FSBL 的行为比如修改 PS 侧 MIO 配置或 DDR 参数思路应该是回到 Vivado 里去改硬件约束重新导出 XSA再重新构建 PetaLinux 工程。手动去改 FSBL 源码属于很低级的操作手法除非你在做极底层的定制否则我不建议碰。3.3 boot.scr 里到底写了什么一段很少有人拆开看的 U-Boot 脚本petalinux-build之后boot.scr 会出现在 images/linux 目录下。你可以用mkimage -l boot.scr查看它的内容。默认情况下它告诉 U-Boot 从 mmc 0:1 分区去加载 image.ub设置 bootargs然后 bootm 启动。如果你用双分区方案一个 FAT 分区放启动文件一个 ext4 分区放 rootfsboot.scr 里还需要指定 root/dev/mmcblk0p2 这样的参数。这里有个调试技巧把 boot.scr 解包出来改掉 bootargs再重新打包这样就能绕过 PetaLinux 的配置界面直接改启动参数。对快速验证尤其管用比如你想临时加一个mem512M限制内存不需要重新 build 整个工程。3.4 image.ub 的内部结构与 FIT 源文件image.ub 是一个 FITFlattened Image Tree格式的镜像里面封装了内核、设备树、ramdisk。PetaLinux 会在构建过程中生成对应的 .its 文件这个文件描述了 image.ub 的组成结构。你可以看到每个子镜像都有自己的 hash 值和加载地址U-Boot 在启动时会校验这些 hash保证镜像完整性。如果只想更新内核可以单独编译内核后用petalinux-package --image重新打包不需要对整个工程做完整 build。这个操作能大幅缩短开发迭代周期特别适合在做驱动开发和内核调试时使用。4. 制作 SD 卡启动卡分区、格式化、镜像写入与故障排查4.1 单分区还是双分区我的建议是双分区网上很多教程会让你把整张 SD 卡只分成一个 FAT32 分区然后直接把 BOOT.BIN、boot.scr、image.ub 三个文件拷进去。这个方案能用但很粗糙——rootfs 也只能塞到 FAT32 里而 FAT32 对文件权限、符号链接的支持非常差跑 Linux 系统是会出问题的。我更推荐双分区方案第一个分区FAT32大小 512MB存放 boot.bin、boot.scr、image.ub第二个分区ext4占据剩余空间存放 rootfs这样既保证了启动文件的易访问性又给了 rootfs 一个合适的文件系统环境。后面做驱动开发、交叉编译部署时权限问题会少很多。4.2 用 fdisk 和 mkfs 手动制作启动卡Linux 下制作启动卡的完整命令流程大致如下sudo fdisk /dev/sdb # 删除旧分区建立新分区表第一个分区类型设为 c (FAT32)第二个分区类型设为 83 (Linux) sudo mkfs.vfat -F 32 -n BOOT /dev/sdb1 sudo mkfs.ext4 -L rootfs /dev/sdb2 sudo mount /dev/sdb1 /mnt/boot sudo mount /dev/sdb2 /mnt/rootfs sudo cp images/linux/BOOT.BIN images/linux/boot.scr images/linux/image.ub /mnt/boot/ sudo tar -xf images/linux/rootfs.tar.gz -C /mnt/rootfs这里有个所有教程都不会提醒你的细节拷贝完文件后一定要用sync命令确保数据落盘再卸载分区。很多人急着拔卡导致启动文件写入不完整上电后卡在 BootROM 阶段还以为是镜像的问题。做嵌入式开发的耐心等那几秒钟的 sync 真的值得。4.3 从串口终端定位启动卡故障把启动日志当作第一手证据制作完启动卡后用串口连接开发板波特率一般是 115200上电后观察启动日志。常见的现象我列个表现象可能原因排查方向完全没有输出串口配置不对或板子没上电确认波特率、串口线、电源指示灯输出停留在 BootROM 阶段BOOT.BIN 不存在或损坏检查 FAT32 分区是否有 BOOT.BIN卡在 U-Boot 之后boot.scr 加载失败或分区不对查看 U-Boot 的ls mmc 0:1输出内核启动后挂在 Waiting for root devicerootfs 没找到或文件系统损坏检查 bootargs 中的 root 参数和 ext4 分区我自己遇到最头疼的一种情况是BOOT.BIN 能加载U-Boot 也起来了但内核启动后一直重启。后来发现是 DDR 初始化参数跟板载内存颗粒不匹配需要在 FSBL 里配置正确的 DDR 参数。这种情况在官方评估板上很少见但一旦用了非标的核心板就得重新审视 FSBL 的 DDR 初始化配置。5. FPGA 学习从外设到高速接口按难度排一条我实践过的路线5.1 入门项目选择数码管动态显示、信号发生器、温控风扇很多人问 FPGA 入门到底做什么好我的答案不是做流水灯而是数码管动态显示。别小看这个项目它背后牵涉到分频时钟、计数器、段选/位选的刷新时序、以及多路复用这几个基础概念。把数码管动态显示搞明白你对FPGA 是并行硬件而不是顺序执行程序这件事会有切身体感。接着可以做 DDS 信号发生器这个项目引入了相位累加器的概念是后面做数字信号处理的雏形。配套的按键调节频率和数码管显示设置值能把你的状态机设计能力锻炼起来。再往后温控风扇是个特别好的综合项目温度传感器采集、PID 控制算法、PWM 调速、LCD 显示一整套信号链下来基本覆盖了 FPGA 工业控制场景的大部分基础模块。5.2 通信接口路线从 UART、SPI、IIC 到自定义协议基础项目做完就该碰接口了。优先级最高的三个接口是 UART、SPI、IIC。UART 帮你理解异步通信的起始位、停止位、波特率产生SPI 让你理解主从模式和时钟极性IIC 则是对开漏输出和时序要求的实战训练比如跟 EEPROM 读写就是最经典的练习项目。这些接口的官方文档和 Xilinx IP 手册都写得非常详细但我更建议先用 Verilog 自己写一遍哪怕写得丑、代码冗余也要把时序图上的每一个阶段跟 RTL 代码对应起来。等跑通了再用 IP 核替换你才能真的看懂 IP 核配置界面里那些选项的含义。我之前看过很多人直接拖 IP 核连设备地址和寄存器位宽都搞错后面调试得怀疑人生。5.3 高速接口与图像处理LVDS、MIPI、PCIe 以及 ISP 去马赛克接口进阶到高速信号后难度立刻上一个台阶。LVDS 接收要关注时钟通道和数据通道的对齐MIPI 则涉及通道映射、差分阻抗匹配以及协议层解析PCIe 更是直接把复杂度拉满光链路训练和对齐机制就能写一本书。图像处理方向我建议从最简单的灰度转换和边缘检测开始再逐渐过渡到 ISP 流水线里的去马赛克Demosaic、坏点校正、自动白平衡等算法。很多同学在做去马赛克时有个误区直接用 OpenCV 的算法模型往 FPGA 里搬结果资源占用爆炸。FPGA 图像处理的本质是用流水线设计实现像素级运算你得先把双线性插值这样最简单的算法用 Verilog 写出来理解行缓存和窗口缓存的机制再谈复杂算法。5.4 FPGA 与 PCB、电源设计之间的互动为什么硬件工程师也要懂一点 FPGA搜索热词里有一个特别有意思的FPGA 与 PCB 开发如何互动。这个其实是产品开发中非常现实的问题。FPGA 的引脚分配会影响 PCB 布线难度内部 Bank 的电平标准不同高速接口的布线要求也不一样。如果 FPGA 工程师在综合之前就随意分配引脚到 PCB 设计阶段会发现绕线绕到崩溃。反过来PCB 工程师也应该了解 FPGA 的电源轨需求。FPGA 核心电压和 IO 电压的启动时序有要求如果电源设计不满足时序要求FPGA 可能出现上电复位不正常的问题。这类问题不像逻辑 Bug 那样能靠仿真发现往往到了硬件调试阶段才暴露排查起来特别痛苦。我做过的几个项目里最省事的方式是原理图阶段就同步 FPGA 引脚规划PCB 布局布线阶段让 FPGA 工程师参与评审。6. ZYNQ 裸机开发与 Linux 应用从串口、USB 到 Qt 上位机6.1 裸机 USB 通信方案为什么很多人最后选了 libusbZYNQ 裸机 USB 是一个经常被搜索的热词但很多人没意识到裸机驱动 USB Host 的复杂度远超预期。ZYNQ 的 USB 控制器是 Synopsys DWCOTG IP用裸机驱动它你需要处理中断、DMA、描述符链表、端点调度等一大堆细节。如果只是需要与 PC 或其它 USB 设备通信我建议优先考虑跑一个轻量级 Linux然后在 Linux 里用标准 USB 驱动上位机通过 libusb 访问端点会省掉好几周的裸机驱动开发时间。基于 libusb 的上位机方案核心工作其实就三步用libusb_init初始化库、用libusb_open_device_with_vid_pid打开设备、然后用libusb_bulk_transfer做批量传输。整体开发效率比裸机方案高一个数量级。真正需要裸机 USB 的场景往往是资源受限、不能跑 Linux 的嵌入式项目这时候才值得去啃那份复杂的 USB 协议栈。6.2 Qt 的 ZYNQ serialport 库交叉编译要点另一个高频热词是 Qt zynq serialport 库编译。简单来说Qt 的 serialport 模块在源码里是独立于核心库的在某些 Qt 版本里默认不会跟着主库一起编译。交叉编译时必须显式进入 qtserialport 源码目录编译并安装cd qtserialport-src /path/to/qmake make -j4 sudo make install交叉编译完成后在 Qt 工程文件里添加QT serialport再用对应的交叉编译器构建。这里最容易踩的坑是主机环境的 Qt 与交叉编译环境的 Qt 版本不一致导致头文件和库文件冲突。建议把交叉编译的 Qt 安装到独立目录并通过qmake的-spec参数指定设备平台配置。6.3 QT 上位机与 FPGA 联调时的几个常见恶心问题联调过程中我发现有几个问题几乎每做一个项目都会出现。第一个是串口打开失败多半是权限问题要给串口设备文件加权限或者将用户加入 dialout 组。第二个是数据校验和错误但硬件端其实没有异常——这种问题通常是硬件端的位序定义和上位机不一致造成的尤其是多字节数据的大端小端差异。第三个是上位机接收到的数据缺字节这个往往是 USB 转串口芯片的驱动缓冲区设置问题增大缓冲区或改用流控能解决。7. 关于 FPGA 职业方向、面试高频考点与工具链选择的现实建议7.1 FPGA 算法实现工程师到底是做什么的搜索热词里 fpga 算法实现属于什么工程师 说明很多人对这个岗位的定义感到困惑。算法实现工程师的核心工作是把数字信号处理、图像处理、AI 推理等算法通过 RTL 实现在 FPGA 上但他不是算法研究员——算法研究员关注的是精度和效果而算法实现工程师要额外面对资源占用、时序约束、位宽截位等硬件问题。这个岗位最考验人的一点是你要能在算法和硬件之间做平衡。比如一个浮点滤波器直接实现浮点运算在 FPGA 上不仅资源爆炸时序也不容易收敛通常要转换为定点运算并合理截位。这需要你对 FPGA 的 DSP Slice、Block RAM 结构非常了解还要有不错的数字信号处理基础。如果你打算走这条路建议提前把数字信号处理、数字图像处理、计算机体系结构这些课补扎实。7.2 面试常见问题背后的考察点FPGA 面试最常见的问题不是那些复杂算法反而是基础概念同步复位和异步复位的区别、亚稳态的形成与消除方法、跨时钟域处理的常用手段、阻塞赋值与非阻塞赋值的区别。这些题目看似简单实际上在考察你有没有真正理解 FPGA 的设计哲学——并行性和时序性。有意思的是fpga 复位信号亚稳态 单独成为一个热搜词说明不少人在项目中真实踩过这个坑。处理跨时钟域的复位释放标准的做法是用异步复位、同步释放电路即用两级触发器同步异步复位信号再送给各个模块。如果你面试时能把这个原理和实际案例结合讲清楚会比单纯背概念强得多。7.3 FPGA 工具链选择Xilinx、Altera、易灵思、高云怎么选工具链的选择其实是跟着项目和公司需求走的。Xilinx现在叫 AMD的 Vivado 生态最完善学习资源也最多PetaLinux 更是 ZYNQ 开发的必选工具目前国内招聘岗位讲 Xilinx 平台的比例是最高的。Altera 现在归 Intel 所有对应的 Quartus Prime 软件对新手相对友好部分学校教学也在用。ModelSim-Intel Starter Edition 免费版适合做仿真作为入门学习工具很合适。国产 FPGA 这两年发展很快易灵思和高云的开发工具链有很多针对国内用户的优化文档和培训资源也越来越丰富。在一些特定行业比如通信、工业控制国产 FPGA 的交付速度和本地化支持都有明显优势。我的建议是如果目标是就业优先学 Xilinx如果是个人兴趣或者做低成本项目国产 FPGA 很值得关注。7.4 FPGA 到底是不是夕阳产业 这个问题的真实答案网上经常有人问 FPGA 还有没有前途我的观点是FPGA 作为灵活的可编程硬件在通信、汽车电子、工业控制、视频处理、航天军工等领域依然是不可替代的。GPU 和 ASIC 在某些场景确实比 FPGA 有优势但 FPGA 最大的价值在于可重构和快速迭代。尤其现在异构计算的趋势很明显FPGA 经常被用作加速卡和原型验证平台。另外Pytorch 与 FPGA 结合也是最近特别火的方向——用 FPGA 做 AI 推理加速在低延迟和功耗敏感的场景下很有优势。虽然各家大厂都在推专用 AI 芯片但灵活性和低成本切入使得基于 FPGA 的 AI 加速方案仍然有大量落地案例。如果你打算长期深耕这行与其担心红利期过了不如把高速接口、Linux 驱动、数字信号处理这些核心竞争力搞好到哪儿都用得上。8. 我给新手的学习节奏建议和一些很实用的工具8.1 以项目为主线学习而不是以教材为主线我接触过很多自学 FPGA 的朋友最大的问题不是不努力而是太执着于把教材从头啃到尾。看完了《Verilog HDL 高级数字设计》前三章一打开 Vivado 还是很茫然。正确的姿势是直接找一个不太难的项目比如数码管动态显示然后为了完成这个项目去查 Verilog 语法、看时序图、看波形仿真遇到什么问题解决什么问题。这跟学编程是一个道理光看语法书是写不出程序的。Verilog 必须要在工程实践里才能真正理解什么叫寄存器传输级描述什么叫组合逻辑和时序逻辑的区别。仿真是你的好朋友Vivado 自带的仿真工具或者 ModelSim 都行重点是养成写完代码先看波形的习惯造成功能不正确和时序不满足的 bug都能在波形阶段快速定位。8.2 用好官方文档、GitHub 和社区但别当伸手党FPGA 学习资料其实非常多Xilinx 官方文档有几千页UG 系列覆盖了从入门到精通的全部内容。很多人看到这个体量直接吓退了其实不用全读带着问题去查就好。比如你要用 AXI 接口就去查 AXI Reference Guide查到你需要的那部分理解透彻就足够。GitHub 上也有大量开源的 FPGA 项目从入门级的按键控制 LED 到复杂的图像处理加速器都有。我特别推荐的做法是找一个目标项目尝试先读懂它的代码结构理解它为什么这么设计模块然后自己修改或重新实现一个模块。这个过程比跟着教程敲代码有效得多因为你在被迫思考而不是机械搬运。8.3 一块趁手的开发板比几十个视频课更有价值最后一条建议很现实手里要有一块板子。我看过很多零基础一个月入门 FPGA的网课老师讲得确实不错但学生只看视频不练手看完四五个小时连一个 LED 都没点亮这种学习效率极其低下。建议根据预算选一块开发板黑金、正点原子、米联客都有对应的 ZYNQ 或者纯 FPGA 系列入门级几百块的板子足够用到你搞清楚基础外设和接口了。我的建议是宁可买一块能跑 PetaLinux 的 ZYNQ 开发板也不要买一块只能做逻辑实验的纯 FPGA 板。因为前者既能让你学 FPGA 逻辑又能让你接触嵌入式 Linux 开发后面做复杂项目时更是必需品。一次性投资到位省得学了一半再换平台、重学工具链。学习环境这块我到现在还是保留了一个 Ubuntu 22.04 的独立硬盘分区把所有 FPGA 和 PetaLinux 工具固定在上面既稳定又方便备份迁移比在虚拟机上折腾舒服得多。