当前位置: 首页 > news >正文

基于ZCU104的Petalinux定制:从XSA到启动镜像的完整构建流程

1. 环境准备:搭建你的Petalinux“厨房”

拿到一块ZCU104开发板,想让它跑起来一个为你硬件量身定制的Linux系统,感觉是不是有点无从下手?别慌,这个过程就像做一道大餐,你得先把厨房(开发环境)收拾利索,把食材(工具链)备齐。我刚开始玩Zynq MPSoC的时候,也在这第一步上折腾了好久,今天就把我踩过的坑和总结的经验,掰开揉碎了讲给你听。

首先,你得有个“厨房”——也就是一台运行Linux的电脑。我强烈推荐使用Ubuntu 18.04 LTS,这是Xilinx官方文档里反复验证过的版本,兼容性最好,能帮你避开一堆莫名其妙的依赖库问题。用虚拟机(比如VMware或VirtualBox)安装一个是最省事的方案,记得分配足够的资源,建议CPU给4核以上,内存至少8GB,硬盘空间留出100GB以上,因为后续编译过程会产生大量中间文件。我试过在资源紧张的虚拟机上编译,那速度真是“感人”,等得花儿都谢了。

厨房有了,接下来就是安装“厨具套装”——Petalinux。这里有个关键点:Vivado、Petalinux和BSP(板级支持包)的版本必须严格匹配。比如你Vivado用的是2020.2,那Petalinux和BSP也得是2020.2。混用版本是新手最常见的“翻车”现场,轻则编译报错,重则生成的镜像根本无法启动。去Xilinx官网下载对应版本的Petalinux安装包,通常是一个很大的.run文件。下载前需要注册账号,这个步骤不能省。

安装前,有一堆系统依赖包需要搞定。别嫌麻烦,一个一个装,这是地基。打开终端,执行下面这条“万能”命令,它基本涵盖了Petalinux所需的所有依赖:

sudo apt-get install -y gcc git make net-tools libncurses5-dev tftpd zlib1g-dev libssl-dev flex bison libselinux1 gnupg wget diffstat chrpath socat xterm autoconf libtool tar unzip texinfo zlib1g-dev gcc-multilib build-essential zlib1g:i386 screen pax gzip gawk

装完之后,有个小细节要注意:Petalinux要求系统的/bin/sh链接到bash,而不是dash(Ubuntu默认可能是dash)。检查一下:

ls -l /bin/sh

如果显示链接到dash,就用下面命令改过来,在弹出的对话框里选择“否”:

sudo dpkg-reconfigure dash

现在可以安装Petalinux了。我习惯把它安装到/opt目录下,结构清晰。先创建目录并修改权限(记得把yourusername换成你的实际用户名):

sudo mkdir -p /opt/pkg/petalinux/2020.2 sudo chown -R yourusername:yourusername /opt

然后运行安装程序,指向刚才创建的目录:

./petalinux-v2020.2-final-installer.run --dir /opt/pkg/petalinux/2020.2

安装过程会弹出一大堆许可协议,一路按回车直到最后输入y同意即可。安装时间取决于你的机器性能,喝杯咖啡等等。

安装完成后,每次打开新终端,都需要“激活”Petalinux环境。为了省事,我们把它设为别名。编辑你的~/.bashrc文件,在末尾加一行:

alias sptl='source /opt/pkg/petalinux/2020.2/settings.sh'

保存后,执行source ~/.bashrc让配置生效。以后只要在终端里输入sptl,就进入了Petalinux的工作环境。至此,你的“厨房”就准备妥当了,锅碗瓢盆、油盐酱醋一应俱全,可以开始我们的“烹饪”之旅了。

2. 工程创建与硬件导入:给Linux系统一张“硬件蓝图”

环境好了,我们正式开工。第一步是创建一个Petalinux工程,并告诉它:“嘿,这是我们的硬件长什么样。” 这个“硬件说明书”就是Vivado导出的XSA(Xilinx Support Archive)文件。我建议你建立一个清晰的工作目录,比如在用户目录下建一个workspace,里面再分门别类放好各种文件,这样以后找东西不抓瞎。

mkdir -p ~/workspace/{BSP, XSA, projects}
  • BSP:存放从官网下载的板级支持包(.bsp文件)。对于ZCU104,一定要下载和你Petalinux版本匹配的BSP,它包含了针对这块板子的基础配置,能省去大量手动配置的功夫。
  • XSA:把你从Vivado里File -> Export -> Export Hardware...(记得勾选Include bitstream)生成的.xsa文件放进来。这个文件包含了你的PL(可编程逻辑)设计信息、PS(处理器系统)配置以及比特流。
  • projects:用来存放后续创建的Petalinux工程。

进入工作目录,并激活Petalinux环境:

cd ~/workspace sptl

接下来,使用BSP作为模板创建工程。这就像用预制好的面团做披萨底,比自己从头和面要快得多,也更容易成功:

petalinux-create -t project -n my_zcu104_linux -s ./BSP/xilinx-zcu104-v2020.2-final.bsp

命令执行后,会在当前目录下生成一个名为my_zcu104_linux的文件夹,这就是你的Petalinux工程目录。

现在,要把我们自定义的硬件信息“注入”到这个工程里。进入工程目录,执行配置命令,并指定XSA文件的路径:

cd my_zcu104_linux petalinux-config --get-hw-description ../XSA/design_1_wrapper.xsa

这个命令会启动一个基于文本界面的配置菜单。第一次运行时,它会解析XSA文件,自动识别出处理器型号(如Zynq UltraScale+ MPSoC)、内存大小、外设等信息,并加载到工程配置中。这里我们首先要做的是一个关键选择:系统从哪里启动?

对于ZCU104评估板,我们通常从SD卡启动。在配置菜单中,按如下路径导航:

Image Packaging Configuration ---> Root filesystem type (INITRAMFS) ---> (X) SD card

选择SD card,然后按右方向键选择Save,回车确认保存配置文件名为.config,最后选择Exit退出。这一步决定了最终生成的根文件系统镜像格式,以及启动脚本中寻找根文件系统的位置。如果选错,系统启动时会在最后一步卡住,提示找不到根文件系统,我早期就因为这个坑折腾了半天。

配置完成后,你会发现在工程目录下生成了一个components/plnx_workspace/目录,里面包含了从XSA解析出的设备树源文件等。这意味着Petalinux已经“认识”了你的硬件。这一步是后续所有软件配置的基础,相当于给即将诞生的Linux系统绘制了一张准确的“硬件地图”。

3. 深度定制:内核、根文件系统与关键的内存保留配置

基础工程搭好了,但这是个“通用”系统。我们的硬件设计里,PS(ARM处理器)和PL(FPGA逻辑)之间是需要频繁交换数据的,这就需要对系统进行深度定制。核心任务有三件:配置Linux内核、定制根文件系统,以及最最重要的一步——为PS-PL数据交互预留专用的内存区域

先说说内核配置。虽然BSP提供了默认配置,但了解如何微调很有必要。运行:

petalinux-config -c kernel

这会进入内核的详细配置菜单,里面有成千上万个选项。对于初学者,大部分保持默认即可。但有一个选项强烈建议你检查,它关系到PS能否直接访问物理内存:

Kernel hacking ---> [*] Filter access to /dev/mem

确保这个选项没有被选中(即括号内是空格,不是*或M)。如果被选中,内核会阻止通过/dev/mem设备访问所有物理内存,这会导致我们后续在PS端用mmap映射PL器件地址或保留内存时失败。BSP默认配置通常是关掉的,但检查一下更放心。检查完毕后,保存退出。

接下来是根文件系统配置。这里可以添加你需要的软件包,比如调试工具gdbstrace,网络工具iperf,或者python3等。命令是:

petalinux-config -c rootfs

菜单里分为Filesystem Packages多个子类,你可以按需勾选。初期为了简化,可以全部保持默认。等系统跑起来后,如果发现缺少某个命令或库,再回来添加也不迟。

现在来到整个定制流程的灵魂所在——设备树(Device Tree)修改。设备树是Linux内核用来描述硬件拓扑结构的一种数据格式。我们要在这里告诉内核:“有一块内存区域是保留给PS和PL进行数据共享的,你别拿去干别的了。”

为什么这步如此关键?想象一下,PS和PL是工厂里的两个车间,它们需要共享一个仓库来传递零件。这个仓库就是一段物理内存(DDR中的一部分)。如果Linux内核不知道这个仓库被预定了,它可能把这里当成普通内存,分配给其他程序使用。结果就是,PS往里面写数据,PL来读,却发现里面全是别的程序的“垃圾数据”,或者更糟,PL写入的数据被其他进程覆盖,导致系统崩溃。

具体怎么做呢?在Petalinux工程里,自定义设备树配置放在project-spec/meta-user/recipes-bsp/device-tree/files/目录下。我们需要修改或创建system-user.dtsipl-custom.dtsi文件。根据我的实战经验,在Petalinux 2020.2及以后版本,更稳妥的做法是修改pl-custom.dtsi

假设我们在Vivado设计中,为数据交互预留的DDR地址是从0x1000_0000开始,大小为0x0DF9_E000(约224MB)。那么pl-custom.dtsi文件内容应该如下:

/ { reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges; buffer@0x10000000 { no-map; reg = <0x0 0x10000000 0x0 0x0DF9E000>; }; }; };

我来解释一下关键字段:

  • reserved-memory:这是一个节点,声明了系统中所有需要保留的内存区域。
  • buffer@0x10000000:我们自定义的保留区域节点名,地址作为名字的一部分便于识别。
  • no-map:这个属性非常重要!它告诉内核,在系统启动的早期阶段,不要为这块内存创建页表映射。也就是说,Linux的内存管理系统完全看不到这块内存,从而保证了它的独占性。
  • reg = <0x0 0x10000000 0x0 0x0DF9E000>:定义内存区域。前两个数字是起始地址的高32位和低32位(对于Zynq UltraScale+,地址是64位的,所以这里高32位是0x0)。后两个数字是区域大小的高32位和低32位。这里的意思就是从0x1000_0000开始,分配0x0DF9_E000字节的内存。

修改保存后,Petalinux在编译时会自动将这个文件的内容与从XSA解析出的基础设备树合并。这样,编译出来的Linux内核在启动时,就会乖乖地把这块内存圈起来,留给我们PS和PL的数据交互专用。这一步配置是否正确,直接决定了后续应用程序和FPGA逻辑能否正常通信,可以说是“失之毫厘,谬以千里”。

4. 系统构建与镜像打包:从源码到可启动的SD卡

所有配置都敲定了,接下来就是激动人心的编译构建环节。这个过程有点像把准备好的食材下锅烹饪,最终做出一盘菜。你只需要输入一个命令:

petalinux-build

然后,就可以去休息一下了。首次完整构建耗时较长,在我的台式机(i7,32GB内存)上大概需要30分钟到1个小时,具体取决于你选择的软件包数量和机器性能。终端里会飞速滚动各种编译信息,只要没有红色的Error提示,就安心等待。这个过程会依次编译U-Boot(启动引导程序)、Linux内核、设备树二进制文件(.dtb)以及根文件系统。

构建完成后,所有生成的镜像文件都存放在images/linux/目录下。但这时候它们还是分散的,我们需要把它们“打包”成一个或几个可以直接烧录到SD卡的文件。这就需要用到打包命令:

petalinux-package --boot --fsbl images/linux/zynqmp_fsbl.elf --pmufw images/linux/pmufw.elf --fpga images/linux/system.bit --u-boot images/linux/u-boot.elf --force

让我拆解一下这个命令的每个部分:

  • --boot:告诉工具我们要生成启动镜像。
  • --fsbl:指定First Stage Bootloader的ELF文件。FSBL是上电后第一个运行的软件,负责初始化PS、加载PL比特流等。
  • --pmufw:指定Platform Management Unit Firmware的ELF文件。PMU负责电源管理、系统监控等。
  • --fpga:指定包含你PL设计的比特流文件(.bit)。这个文件决定了你的FPGA逻辑功能
  • --u-boot:指定第二阶段的引导程序U-Boot的ELF文件。
  • --force:如果输出文件已存在则强制覆盖。

执行这个命令后,它主要做两件事:

  1. fsbl.elfpmufw.elfsystem.bitu-boot.elf四个文件,按照Zynq MPSoC启动要求的特定格式,拼接生成一个BOOT.BIN文件。这个文件会被启动ROM首先加载。
  2. 将Linux内核镜像(Image)、设备树二进制文件(system.dtb)以及根文件系统镜像(可能是rootfs.cpio.gzrootfs.ext4,取决于你的配置)打包生成一个image.ub文件。这是一种FIT(Flattened Image Tree)格式的镜像,U-Boot能够识别并从中加载内核和根文件系统。

打包完成后,images/linux/目录下我们最关心的就是这三个文件:

  • BOOT.BIN:包含所有启动阶段固件和FPGA比特流的第一启动镜像
  • image.ub:包含Linux内核、设备树和根文件系统的系统镜像
  • boot.scr:U-Boot的启动脚本文件,告诉U-Boot从哪里加载image.ub等参数。

最后一步,就是把这“三剑客”拷贝到SD卡。准备一张FAT32格式的SD卡(容量8GB以上足够),插入电脑。将上述三个文件直接复制到SD卡的根目录(注意不是任何文件夹内)。对于ZCU104,SD卡插槽在板子侧面,将制作好的SD卡插入,上电,如果一切顺利,你应该能在串口终端里看到U-Boot的启动信息,接着是Linux内核解压、启动,最后出现登录提示符。那一刻的成就感,绝对是驱动你继续深入探索嵌入式Linux世界的最佳燃料。

http://www.jsqmd.com/news/473439/

相关文章:

  • 【ADC延迟剖析】从数字滤波器到系统响应:SAR与ΔΣ ADC的延迟本质与应用抉择
  • 深入剖析Antd Table固定列布局:从空白间隙到完美适配
  • WinCC 条形图详细使用说明
  • LaTeX技巧:高效绘制带自定义符号的学术统计表格
  • 从拉格朗日插值到门限秘密:Shamir方案核心原理解析
  • 基于GD32E230的雨滴传感器模块驱动移植与ADC/GPIO双模式数据采集实战
  • 你知道普通产品经理和AI产品经理有什么区别吗?
  • HY-MT1.5实时翻译场景测试:边缘设备上的低延迟表现
  • 2026最新野草助手下载安装教程(附官网安装包+图文详解) - xiema
  • 51单片机实战:IIC协议驱动24C02实现LED动态控制
  • 一图看懂LangChain、LangGraph、LangSmith全家桶
  • 基于SpringBoot Actuator与Kubernetes的优雅停机策略优化实践
  • 广州市瑞道化工有限公司核心产品 :尼龙成核剂 - 妙妙水侠
  • Cadence Allegro实战:从零到一构建专业PCB设计流程
  • 转行AI产品经理,90%的人第一步就走错了!
  • 高性能图像处理库
  • AutoDL实战指南:1)平台核心优势解析 2)实例创建与配置 3)Trae远程开发环境搭建
  • 【MCP实战】利用端口转发实现Claude Desktop跨平台访问远程Linux服务器
  • 从双目交汇到三维感知:立体视觉中的深度估计实战
  • Gemma-3-12B-IT WebUI开箱即用:一键部署与参数调节指南
  • STA 静态时序分析 第三章——标准单元库中的高级功耗建模与优化
  • nnUNet v2 进阶指南:从UKAN模型集成到3D数据实战
  • 38K红外遥控电路设计实战:从发射管选型到接收电路优化
  • 【WinForm实战指南】DataGridView控件:从数据绑定到界面交互的完整实践
  • LN-DETR:多尺度特征融合与通道Transformer在肺结节检测中的协同优化
  • 提升研发效能:用快马一键生成阿里P10推崇的工程化基础框架
  • 深入剖析pip更新报错:从PermissionError到权限管理最佳实践
  • Python实战:卡方检验在医学数据分析中的应用
  • FireRedASR-AED-L开源大模型:1.1B参数本地语音识别技术深度解析
  • ESP01S WIFI模块与ColorEasyDuino开发板AP/STA模式通信实战