ARTICLE DETAIL

资讯详情

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

PetaLinux嵌入式Linux开发入门:从Zynq工程创建到SD卡启动全流程

PetaLinux嵌入式Linux开发入门:从Zynq工程创建到SD卡启动全流程 1. 从零开始认识PetaLinux为什么搞Zynq开发绕不开它先聊点实际的。做Zynq、Zynq UltraScale或者Versal这类异构SoC的嵌入式开发大家早晚都会撞上同一个问题ARM核上要跑Linux但Linux不是像裸机程序那样编译个.elf就能跑的。你得有一套完整的软件栈——FSBL、ATF、U-Boot、内核、设备树、根文件系统再加上与Vivado硬件工程的对应关系这些环节又互相依赖手动挨个处理会相当痛苦。PetaLinux就是Xilinx现在叫AMD官方推出的嵌入式Linux开发工具本质上是基于Yocto做了一层深度封装专门解决从Vivado导出的硬件工程到生成可在目标板上启动的Linux系统镜像这条完整链路。它能做的事情大致包括根据硬件平台自动生成FSBL、PMUFW、ATF、U-Boot等启动组件自动匹配内核版本、设备树生成规则并支持手动修改提供menuconfig式的内核、rootfs配置方式降低上手门槛一键打包生成BOOT.BIN、boot.scr、image.ub等最终启动镜像提供标准化的SD卡启动镜像制作方式方便快速验证和量产复制这一篇是系列第一讲先把大框架和主流程搭起来涵盖环境准备、工程创建、系统配置、编译打包、SD卡制作与启动验证这几个核心环节。后面的系列文章再逐个深挖设备树修改、驱动集成、根文件系统定制这些细节点。这篇文章适合谁刚接触PetaLinux的嵌入式工程师、在学校做FPGAARM项目的学生、以及从裸机开发转向Linux开发的从业者。如果你已经能用Vivado做出硬件工程至少会导出XSA文件那今天的内容你能完整跟着走一遍。2. 搭建PetaLinux开发环境版本匹配是第一道坎2.1 主机环境推荐与虚拟机配置PetaLinux官方支持Ubuntu的特定LTS版本这一点必须优先确认。以PetaLinux 2025.1为例官方声明支持Ubuntu 22.04但实际测试中Ubuntu 20.04也能用只是偶尔会遇到依赖库不兼容的怪问题。我用的是Ubuntu 22.04虚拟机分配了16GB内存、8核CPU、500GB磁盘空间实际PetaLinux完整编译一次会吃掉80~120GB包括临时文件磁盘别省。需要注意PetaLinux安装本身只需要几十GB但每次构建工程会产生大量中间产物加上Yocto的下载缓存磁盘小了真的会中途崩。另外还有个容易踩的坑不要用Windows的WSL跑PetaLinuxUSB和串口透传支持太差调试时会悔不当初。提示如果你用虚拟机建议把虚拟磁盘预先分配不选动态扩展性能会好很多编译时IO密集尤其明显。2.2 安装步骤与/bin/sh的坑PetaLinux安装过程不复杂但有两个前置条件很关键。第一个是安装依赖库。官方文档有一份依赖包清单按版本不同略有差异。以2025.1为例核心依赖大致包括sudo apt update sudo apt install -y tofrodos iproute2 gawk xvfb 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 libsdl1.2-dev libglib2.0-dev screen pax sysv-rc-conf gperf bzip2 expect dos2unix lrzsz libtool-bin我建议全部复制执行别手动挑。缺少某些库时安装脚本能过但后续编译时会出现各种莫名其妙的perl或python报错。第二个是修改默认shell。Ubuntu 22.04默认/bin/sh指向dashPetaLinux的很多脚本要求bash不切换会在source环境变量时直接报语法错误这是新人最容易卡住的地方。sudo dpkg-reconfigure dash执行后在弹出的界面里选择No让/bin/sh保持指向bash。安装PetaLinux本体chmod x petalinux-v2025.1-installer.run ./petalinux-v2025.1-installer.run --dir /opt/petalinux安装完后设置环境变量。这一步每次打开新终端都要执行建议写进~/.bashrcsource /opt/petalinux/settings.sh验证安装petalinux-version如果能看到版本号环境就OK了。2.3 版本匹配原则PetaLinux与Vivado必须同版本这个必须重点强调PetaLinux的版本必须和生成XSA的Vivado版本严格一致。比如你在Vivado 2023.2里导出的硬件工程就一定要用PetaLinux 2023.2来做系统。版本错配会出现什么情况最常见的是设备树生成报错、U-Boot编译不通过——因为硬件描述里的IP版本和PetaLinux内嵌的驱动版本对不上。我在早期尝试过用2024.1的PetaLinux打开2023.2的XSA结果在petalinux-config --get-hw-description阶段就报了一个关于versal_cips的解析异常排查了一下午才发现是版本问题。所以务实建议下载PetaLinux时把它和对应的Vivado安装包一起下载版本严格锁定省掉后面一大串麻烦。3. 创建PetaLinux工程两种方式的完整对比3.1 使用BSP创建工程如果你是从官方开发板如ZCU102、ZCU106、KR260等开始最简单的方式是下载官方BSPBoard Support Package文件它包含了完整的硬件配置、预设的设备树和经过验证的U-Boot配置。petalinux-create -t project -s /path/to/xilinx-zcu102-v2025.1.bsp cd xilinx-zcu102-v2025.1这种方式创建的工程配置基本已经调好首次编译成功率极高适合新手先跑通整个流程。缺点是很多默认配置是为了通用性设置的后续自定义空间需要自己摸索。3.2 使用硬件工程XSA创建工程重点实际项目中我们大概率是基于自己的硬件平台做开发这时就要用Vivado导出的XSA文件。获取XSA的步骤很简单在Vivado里打开你的工程File - Export Hardware勾选Include bitstream导出后缀为.xsa的文件。然后创建PetaLinux工程petalinux-create -t project --name my_zynq --template zynq cd my_zynq petalinux-config --get-hw-description/path/to/your/hardware.xsa命令里的--template zynq有讲究。PetaLinux 2025.1支持zynq、zynqMP、versal、microblaze等几种模板必须和你的目标芯片平台对应。Zynq-7000系列用zynqZynq UltraScale MPSoC用zynqMPVersal用versal。选错模板后面会有一堆兼容性问题。执行完petalinux-config后会自动打开一个图形化配置界面。这是PetaLinux核心配置入口默认停留的Subsystem AUTO Hardware Settings页面可以在这里看到自动识别的硬件参数。常用的几项配置Linux Components Selection选择U-Boot版本2025.1默认是u-boot-xlnxSubsystem AUTO Hardware Settings - Advanced bootable images storage Settings - boot image settingsBOOT.BIN的存放分区默认选择SD0也就是SD卡FAT32分区Subsystem AUTO Hardware Settings - Advanced bootable images storage Settings - u-boot env partitionU-Boot环境变量存放位置同样保持SD0Image Packaging Configuration - Root filesystem type选择ext4还是INITRAMFS等我们后面制作SD卡通常选ext4首次操作的人看到这个全屏蓝色界面会有点懵其实逻辑很清晰左边是导航树右边是选项。方向键和Enter操作不需要额外学习成本。注意如果petalinux-config界面无法正常显示大概率是缺少ncurses库回到依赖安装那一步补装。3.3 首次配置的核心选项解读我不建议对着menuconfig挨个查但有几个关键项必须说明白。一是根文件系统类型。如果用官方BSP创建工程默认是INITRAMFS也就是内核启动时把rootfs加载到内存里。这种方式的优势是启动快、镜像单一但缺点也很明显所有修改在掉电后丢失不适合日常调试。建议改成ext4Image Packaging Configuration - Root filesystem type - EXT4然后指定一个SD卡分区作为rootfs挂载点比如/dev/mmcblk0p2。二是U-Boot环境变量存储。如果使用ext4 rootfs方案U-Boot要从FAT分区读取boot.scr再从ext4分区加载内核和rootfs。这个链路在后文讲启动流程时会详细展开。三是设备树生成方式。PetaLinux默认在编译时会从硬件描述里自动生成设备树pl.dtsi就是PL侧的IP对应的设备树片段我们后续的驱动设备树修改通常是在project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi里追加内容。这个文件不会被自动覆盖是用户自定义设备树的唯一正确位置。4. 核心配置与镜像编译从menuconfig到最终产物4.1 Linux内核与根文件系统配置进入内核配置界面两条路都行。一种是在工程根目录执行petalinux-config -c kernel这个命令本质上是调用了内核的menuconfig但包装了PetaLinux的配置环境。另一种是直接修改project-spec/configs/config里的配置项然后统一编译。第一种方式更直观适合新手。内核配置里需要关注的核心项包括Device Drivers - DMA Engine Support如果你的PL侧设计了DMA IP要确认相关驱动已开启Device Drivers - Network device support确认网卡驱动是否匹配Zynq平台通常用micrel或cadence系列File systems - DOS/FAT/EXFAT如果要读写SD卡FAT分区保险起见把VFAT打开File systems - Ext4rootfs挂载ext4必须开启根文件系统配置使用petalinux-config -c rootfs这里主要关注几个组件的增删Petalinux Package Groups - petalinux-self-hosted如果不需要在目标板上编译程序可以不勾选减小rootfs体积Petalinux Package Groups - packagegroup-petalinux这一组包含了很多基础工具如dropbearSSH服务、iperf3、ethtool、mtd-utils等按需保留。建议至少保留SSH和网络工具否则调试效率会打折apps - petalinux-initramfs-image如果选用了initramfs方案这里会指定镜像内容做完这些配置退出保存即可。4.2 编译过程与耗时预估编译是整个流程中最耗时的一环首次编译的耗时往往让人怀疑人生petalinux-build以我的实测经验为例8核16线程的机器上首次完整编译Zynq UltraScale工程大约需要2到3个小时取决于网络下载依赖的速度Zynq-7000工程会快一些大约1.5小时。后续增量编译会快很多通常5到15分钟能完成。编译过程中有几点值得注意。一是不要随意中断petalinux-build虽然支持断点续编但有些临时文件状态不一致时反而会引入奇怪的问题。二是编译日志在build/logs目录下如果中途报错从这个目录里找对应组件的日志比看命令行尾部的几行输出有用得多。三是网络问题很常见Yocto需要下载大量软件包源码国内网络环境下很容易超时。如果遇到下载失败可以尝试配置代理或者把DL_DIR目录设定到一个稳定的本地缓存位置。提示petalinux-build -x mrproper可以清理所有临时编译产物回到一个干净的工程状态。如果编译中遇到无法解释的问题这个命令配合重新构建往往能解决疑难杂症。4.3 生成BOOT.BIN、boot.scr、image.ub的完整链路编译完成后下一步是打包生成启动镜像。执行petalinux-package --boot --format BIN --fsbl images/linux/zynq_fsbl.elf --u-boot images/linux/u-boot.elf --pmufw images/linux/pmufw.elf --fpga images/linux/system.bit --force参数含义逐个解释--fsbl指定FSBL文件这是Zynq启动的第一阶段引导程序负责初始化DDR、时钟并把比特流加载到PL侧--u-boot指定U-Boot的elf文件它是第二阶段引导程序--pmufwPMU固件仅Zynq UltraScale平台需要Zynq-7000可忽略--fpgaPL侧比特流包含在BOOT.BIN里系统启动时由FSBL进行加载执行后会在images/linux/下生成BOOT.BIN。紧接着需要生成boot.scr。这是U-Boot启动脚本作用是告诉U-Boot从哪里加载内核、设备树和根文件系统。PetaLinux会自动生成一份默认脚本位于images/linux/boot.scr但它是基于默认配置的如果我们改了分区方案或挂载方式需要手动修改。boot.scr的源文件是project-spec/meta-user/recipes-bsp/u-boot/u-boot-script.bb这个配置里的boot.cmd.default内容大致如下echo Loading image.ub... load mmc 0:1 0x10000000 image.ub setenv bootargs consolettyPS0,115200 root/dev/mmcblk0p2 rw rootwait bootm 0x10000000其中load mmc 0:1表示从mmc设备0的第1分区即FAT32分区加载image.ub到内存地址0x10000000。bootm命令从该地址启动Linux内核。修改后需要使用U-Boot的mkimage工具重新生成boot.scrmkimage -c none -A arm -T script -d boot.cmd boot.scr最后是image.ub。这个文件包含了内核、设备树和可选initrd的打包镜像对应命令petalinux-package --image --format uImage --kernel --dtb --force或者用更通用的方式petalinux-package --image -c kernel --format uImage petalinux-package --image -c device-tree --format uImage执行后生成images/linux/image.ub。这个文件在SD卡方案中会同时承担加载内核和设备树的职责。最终得到的三个关键文件BOOT.BIN、boot.scr、image.ub就是整个启动过程的核心。4.4 从image.ub中提取内核和dtb的小技巧在实际开发中经常需要单独检查内核版本或设备树内容。一种快速方法是从image.ub中提取文件source /opt/petalinux/components/yocto/source/aarch64/fsl-setup-release.sh cd images/linux mkimage -l image.ubmkimage -l会列出镜像内包含的文件清单。如果需要解包提取dumpimage -i image.ub -p 0 kernel.bin dumpimage -i image.ub -p 1 system.dtb这个技巧在调试设备树问题时特别有用不用重新编译工程就能快速确认当前镜像里到底打包了什么内容。5. 制作SD卡启动镜像从格式化到上板启动5.1 SD卡分区方案与前因后果制作启动SD卡前先理解一下Zynq平台从SD卡启动的完整流程上电后BootROM从SD卡的第一个分区FAT32读取BOOT.BINFSBL初始化DDR加载比特流到PL然后把U-Boot加载到DDR运行U-Boot读取FAT分区中的boot.scr执行启动脚本boot.scr把image.ub加载到内存解析出内核和设备树并传递bootargs给内核内核启动后根据bootargs中的root/dev/mmcblk0p2挂载ext4分区的根文件系统基于这个流程SD卡只需要两个分区第1分区FAT32存放BOOT.BIN、boot.scr、image.ub第2分区ext4存放根文件系统分区和格式化命令如下sudo fdisk /dev/sdX进入fdisk后依次操作o # 创建新的空分区表 n # 新建分区 p # 主分区 1 # 分区号1 回车 # 起始扇区默认 512M # 大小512M t # 修改分区类型 c # W95 FAT32 (LBA) n # 新建第二个分区 p # 主分区 2 # 分区号2 回车 # 起始扇区默认 回车 # 结束扇区默认用满剩余空间 w # 保存退出然后是格式化sudo mkfs.vfat -F 32 /dev/sdX1 sudo mkfs.ext4 /dev/sdX2注意操作前务必确认/dev/sdX确实是SD卡而不是你的系统盘。可以用lsblk查看当前系统的磁盘列表对照容量和挂载点再操作。这个失误代价太大值得反复确认。5.2 烧录文件与根文件系统拷贝分区完成后把生成的文件拷贝到FAT分区把根文件系统解压到ext4分区。# 挂载分区 sudo mount /dev/sdX1 /mnt/boot sudo mount /dev/sdX2 /mnt/rootfs # 拷贝启动文件 sudo cp images/linux/BOOT.BIN /mnt/boot/ sudo cp images/linux/boot.scr /mnt/boot/ sudo cp images/linux/image.ub /mnt/boot/ # 解压根文件系统 sudo tar -xzf images/linux/rootfs.tar.gz -C /mnt/rootfs/ # 同步并卸载 sync sudo umount /mnt/boot sudo umount /mnt/rootfs这里有个细节值得注意rootfs.tar.gz这个文件在编译完成后如果找不到说明你之前配的是INITRAMFS方案。切换回ext4方案后需要在petalinux-config里重新确认Root filesystem type为EXT4然后重新执行petalinux-build再petalinux-package --image才能生成rootfs.tar.gz。5.3 上电启动验证与常见异常识别把SD卡插入开发板连接串口线通常用USB转UART波特率115200打开串口终端开发板设置SD启动模式上电。正常的启动日志会有明显的顺序感先是BootROM阶段的提示如果有打印然后是FSBL阶段打印的DDR初始化、比特流加载信息接着是U-Boot阶段的版本号、编译时间、环境变量加载信息最后是内核阶段出现大量驱动初始化信息并以login:提示符结束常见的异常集中在几个位置如果卡在FSBL阶段且无任何输出大概率是BOOT.BIN和硬件不匹配或者SD卡格式有问题如果U-Boot启动后找不到boot.scr检查分区是否真的是FAT32文件是否确实拷进去了如果内核启动后提示VFS: Unable to mount root fs说明rootfs分区或挂载参数不对重点检查bootargs里的root/dev/mmcblk0p2与实际分区是否一致如果串口完全无输出先确认开发板的启动模式拨码是否指向SD再确认串口连接正确、波特率无误启动成功后输入账号密码PetaLinux默认的root账号密码通常为空直接回车你就正式进入了自己定制的嵌入式Linux系统。这时候可以跑一些基本命令验证uname -a # 查看内核版本 cat /proc/cpuinfo # 查看CPU信息 ifconfig # 查看网络接口状态6. 常见问题与排查技巧实录6.1 版本错配与环境类问题问题现象petalinux-config --get-hw-description报错提示无法解析XSA文件。排查思路先确认Vivado版本和PetaLinux版本是否完全一致不一致直接换版本重来。这是一类问题中最常见的原因。另外还要确认XSA文件是否完整有时从别人那里拷贝的XSA可能损坏可以用文件大小和MD5做初步判断。问题现象source settings.sh后执行petalinux命令提示command not found。排查思路先确认路径是否正确。如果安装在/opt/petalinuxsettings.sh路径是/opt/petalinux/settings.sh。其次是bash与dash的问题回到前面说的dpkg-reconfigure dash步骤检查。6.2 编译期间常见报错速查报错特征常见原因解决办法/bin/sh: 1: perl: not found依赖库缺失或PATH被破坏重新检查perl安装确认系统PATH完整do_compile: Task failed且日志指向网络Yocto源码下载超时或被墙配置国内镜像源或挂代理或提前手动下载放到DL_DIRNo rule to make target ...文件路径含中文或空格把工程放在纯英文无空格路径下unzip: command not found依赖工具缺失补齐apt的依赖包清单ERROR: No space left on device磁盘不足清理petalinux-build中间产物扩大磁盘6.3 启动阶段异常与调试技巧启动阶段的问题排查最有效的两个手段是串口日志和U-Boot交互模式。如果U-Boot阶段报错但不知道具体原因可以在开发板上电时快速按任意键进入U-Boot命令行手动执行启动命令逐步定位问题发生在哪一步。比如# 查看检测到的SD设备 mmc list # 读取boot.scr fatload mmc 0:1 0x10000000 boot.scr source 0x10000000 # 手动加载image.ub fatload mmc 0:1 0x10000000 image.ub bootm 0x10000000每一步的返回结果能直接告诉你问题出在哪个环节——是分区找不到还是文件读取失败还是内核解压失败。关于设备树一个很实用的排查方法是使用U-Boot的fdt命令查看设备树是否被正确加载fdt addr 0x10000000 fdt print /axi这样可以确认设备树内容和预期是否一致避免辛辛苦苦改了dts却没被实际使用。7. 个人经验补充一次完整的SD卡启动配置参考最后分享一个我常用的完整参考流程算是前面所有内容的一个整合示例。假设你已经有了Vivado导出的名为hardware.xsa的文件从零开始到上板启动完整命令串如下# 1. 创建工程 source /opt/petalinux/settings.sh petalinux-create -t project --name example --template zynq cd example # 2. 导入硬件描述 petalinux-config --get-hw-description/path/to/hardware.xsa # 3. 配置rootfs为ext4 # 在menuconfig中Image Packaging Configuration - Root filesystem type - EXT4 # 保存退出 # 4. 编译完整系统 petalinux-build # 5. 打包BOOT.BIN petalinux-package --boot --format BIN --fsbl images/linux/zynq_fsbl.elf --u-boot images/linux/u-boot.elf --fpga images/linux/system.bit --force # 6. 打包image.ub petalinux-package --image --format uImage --kernel --dtb --force # 7. 查看生成的boot.scr默认已生成 ls images/linux/boot.scr然后按第五部分的SD卡制作流程操作即可。在这套流程里我踩过最大的坑是首次编译时为了追求速度用了petalinux-build -j 32结果内存不足直接OOM工程还留下了一堆异常状态。后来学乖了首次编译就老老实实用默认参数。另外就是SD卡分区操作有一回把U盘当成SD卡给格式化了一次教训惨痛从那以后每次操作前都会用lsblk三连确认设备名。希望各位读者别重复这些教训。这个系列后续会继续深入设备树实操、外设驱动集成、自定义应用打包等内容如果你在跟着做的时候遇到问题可以在评论区带上具体报错信息我尽量一一回复。
返回列表