从零开始的PetaLinux实战:亲手点亮你的第一个Hello World

你有没有过这样的经历?手握一块Zynq开发板,Vivado工程已经跑通,FPGA逻辑也烧进去了,但当你想在ARM上跑个Linux程序时,却发现——连个“Hello World”都不知道怎么输出?

别急。这正是我们今天要解决的问题。

本文不讲空泛概念,也不堆砌术语,而是带你 一步一步、从头到尾完整实现一个PetaLinux工程 ,让你亲手在Xilinx Zynq平台上运行起第一个用户程序。整个过程就像搭积木:每一步都清晰可见,每一环都环环相扣。

最终目标很简单:
👉 在Zynq的ARM核心上启动嵌入式Linux系统
👉 运行我们自己写的 helloworld 程序
👉 看到串口终端打出那句熟悉的:“Welcome to PetaLinux World!”

准备好了吗?让我们开始。


为什么选择PetaLinux?

在进入实操前,先回答一个问题: 为什么非要用PetaLinux?不能直接编译内核+根文件系统吗?

当然可以——但代价是巨大的时间成本和出错概率。

想象一下你要手动完成以下工作:
- 写U-Boot配置
- 编译匹配架构的Linux内核
- 手动编写设备树(DTS),确保CPU、内存、串口、GPIO等资源描述无误
- 构建根文件系统(BusyBox或Buildroot)
- 打包BOOT.BIN和image.ub
- 调试启动失败的各种原因……

而这一切,PetaLinux 一条命令就能自动化完成

它基于Yocto Project构建,专为Xilinx器件优化,能自动解析硬件描述文件(HDF/XSA),生成正确的设备树,并集成U-Boot、Kernel、Rootfs全流程构建。更重要的是,它与Vivado无缝对接,真正实现了“硬件设计 → 软件协同”的闭环开发。

换句话说:

PetaLinux = 快速验证 + 减少低级错误 + 官方支持保障

对于初学者,它是入门的捷径;对于工程师,它是量产项目的可靠基础。


搭建你的PetaLinux战场

开发环境要求

在动手之前,请确认你的主机满足以下条件:

项目 推荐配置
操作系统 Ubuntu 18.04 / 20.04 LTS(64位)
内存 ≥8GB(建议16GB)
磁盘空间 ≥100GB(PetaLinux工具链本身约10GB,构建过程会产生大量中间文件)
工具链 已安装 build-essential , libssl-dev , net-tools , ssh , vim 等常用包

💡 小贴士:建议使用原生Linux系统或WSL2(Windows Subsystem for Linux),避免虚拟机性能瓶颈。

安装PetaLinux工具

前往 Xilinx官网下载对应版本的PetaLinux工具 (推荐使用2022.2及以上版本)。解压后执行安装脚本:

./petalinux-v2022.2-final-installer.run /opt/petalinux/2022.2

然后将环境变量加入 .bashrc

source /opt/petalinux/2022.2/settings.sh

重启终端或运行 source ~/.bashrc ,输入 petalinux-version 验证是否安装成功。


创建第一个PetaLinux工程

我们现在要创建一个名为 plnx_helloworld 的工程,目标平台是Zynq-7000系列(如ZedBoard)。

步骤1:初始化工程

petalinux-create -t project --template zynq --name plnx_helloworld

这条命令会:
- 使用Zynq模板创建工程骨架
- 生成标准目录结构
- 初始化Yocto配置文件

稍等片刻,你会看到提示:“PROJECT CREATION COMPLETE”。

进入工程目录:

cd plnx_helloworld

步骤2:配置系统参数

接下来我们要告诉PetaLinux:这个系统长什么样?

运行:

petalinux-config

这是一个基于ncurses的图形化配置界面,你可以用方向键导航,回车进入子菜单。

重点关注以下几个选项:

✅ Subsystem AUTO Configuration Settings

Advanced bootable images storage Setting
勾选 fpga manager (如果你要用PL部分)

Default U-Boot fdt File
设置为 system.dtb (确保U-Boot加载正确设备树)

✅ DTG Settings

Machine Name
默认为 zynq-7000 ,保持不变即可

✅ Kernel Settings

Kernel Image Type
选择 uImage (兼容性更好)

✅ Root Filesystem Settings

Root filesystem type
选择 INITRAMFS (调试阶段推荐,所有内容打包进内核镜像,无需挂载SD卡上的ext4分区)

✅ Serial Terminal Settings

Serial Port
确认为 ttyPS0 (这是Zynq PS端UART0的设备节点)

保存并退出(按 Esc 多次,最后选 Save → Exit)。


导入硬件描述(HDF/XSA)

如果你的项目中包含FPGA逻辑(即PL部分),你需要将Vivado导出的硬件平台文件导入PetaLinux。

通常有两种格式:
- .hdf (Vivado 2018及以前)
- .xsa (Vivado 2019+,推荐)

假设你已从Vivado导出了 hardware.xsa 文件,将其拷贝到某路径(例如 /home/user/hw_desc/ ),然后执行:

petalinux-config --get-hw-description=/home/user/hw_desc/

PetaLinux会自动解析该文件,提取以下关键信息:
- CPU类型(单核/双核)
- DDR控制器配置
- 外设地址映射(UART, I2C, SPI等)
- 中断连接关系
- PL侧IP核信息(如有AXI接口)

最重要的是:它会自动生成设备树源码(DTS),位于:

project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi

你可以打开这个文件,查看是否有你添加的自定义IP节点。比如:

amba_pl: amba_pl {
    #address-cells = <1>;
    #size-cells = <1>;
    compatible = "simple-bus";
    ranges;

    my_axi_ip@43c00000 {
        compatible = "xlnx,my-axi-ip-1.0";
        reg = <0x43c00000 0x10000>;
    };
};

这就是软硬件协同的关键桥梁。


编写我们的Hello World应用

现在轮到最激动人心的部分了——写代码!

PetaLinux提供了模板命令来快速创建应用程序模块。

步骤1:生成应用模板

petalinux-create -t apps --name helloworld --template c

这会在工程中创建如下结构:

project-spec/meta-user/recipes-apps/helloworld/
├── helloworld.bb
└── files/
    └── helloworld.c

步骤2:替换源码内容

编辑 files/helloworld.c ,写入以下代码:

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("==================================\n");
    printf("  Welcome to PetaLinux World!\n");
    printf("  This is my first Hello World app.\n");
    printf("  Built with petalinux-build\n");
    printf("==================================\n");
    return 0;
}

非常简单,就是一个标准C程序,打印一段欢迎语。

步骤3:修改BitBake配方文件

打开 helloworld.bb ,你会发现默认使用了 autotools 模板,但我们这里只是单文件编译,不需要复杂的Makefile。因此我们简化它:

DESCRIPTION = "Simple Hello World Application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://helloworld.c"

S = "${WORKDIR}"

do_compile() {
    ${CC} ${CFLAGS} ${LDFLAGS} helloworld.c -o helloworld
}

do_install() {
    install -d ${D}${bindir}
    install -m 0755 helloworld ${D}${bindir}/
}

解释几个关键点:
- ${CC} 是交叉编译器(如 arm-linux-gnueabihf-gcc ),由PetaLinux自动设定
- ${D} 是临时安装根目录(类似 _install/
- ${bindir} 展开为 /usr/bin /bin
- install -m 0755 确保生成的文件具有可执行权限

步骤4:注册应用到根文件系统

为了让PetaLinux知道要把这个程序打包进rootfs,还需要启用它。

编辑文件:

project-spec/configs/rootfs_config

添加一行:

CONFIG_helloworld=y

或者更简单的方法:运行

petalinux-config -c rootfs

进入 User Packages modules helloworld ,用空格选中([*])即可。


构建!一键生成完整系统镜像

一切就绪,现在执行终极命令:

petalinux-build

这个过程可能持续20~60分钟,取决于你的机器性能。期间你会看到大量日志滚动,包括:

  • U-Boot 编译
  • Linux 内核编译(带模块)
  • 设备树编译(.dts → .dtb)
  • 根文件系统构建(含我们的helloworld)
  • 最终打包:BOOT.BIN 和 image.ub

构建成功后,输出文件位于:

images/linux/
├── BOOT.BIN          # 二合一引导镜像(FSBL + U-Boot + bitstream)
├── image.ub          # U-Boot可加载的内核镜像(含Kernel + DTB + Initramfs)
└── rootfs.cpio       # 根文件系统归档(仅当使用initramfs时包含应用)

🎉 恭喜!你已经拥有了可以在Zynq板子上运行的完整Linux系统。


烧录与验证:让Hello World说话

准备SD卡

准备一张FAT32格式化的SD卡,清空内容后将两个文件复制进去:

  • BOOT.BIN
  • image.ub

插入开发板SD卡槽。

连接串口调试

使用USB转TTL线(如FT232RL或CP2102)连接开发板的UART0引脚(通常是JTAG旁边的那个串口),另一端插PC。

查看串口设备名:

dmesg | grep tty
# 输出可能是:ttyUSB1

启动终端监控工具:

screen /dev/ttyUSB1 115200

给开发板上电,你应该能看到U-Boot启动日志:

U-Boot 2022.01 (Aug 10 2023 - 15:23:01 +0000)
Model: Xilinx Zynq Platform
DRAM:  512 MiB
...
Hit any key to stop autoboot:  3

如果不干预,系统会自动加载 image.ub 并启动Linux。

等待几十秒,直到出现登录提示符:

PetaLinux 2022.2 plnx_helloworld /dev/ttyPS0
plnx_helloworld login:

用户名密码都是 root (无密码也可直接登录)。

登录后,在shell中输入:

helloworld

如果一切顺利,屏幕上将出现:

==================================
  Welcome to PetaLinux World!
  This is my first Hello World app.
  Built with petalinux-build
==================================

🔥 成功了!这是属于你的第一个PetaLinux应用!


常见坑点与调试秘籍

别高兴得太早,实际开发中总会遇到各种问题。以下是几个高频“踩坑”场景及应对方法:

❌ 问题1: petalinux-build 报错找不到gcc

现象 :构建过程中提示 sh: gcc: not found

原因 :主机缺少必要的构建依赖

解决方案

sudo apt update
sudo apt install build-essential libssl-dev zlib1g-dev libncurses5-dev

同时确保没有在root下运行PetaLinux(会有权限警告)。


❌ 问题2: helloworld 命令找不到

现象 :系统启动后输入 helloworld 提示 command not found

原因 :应用未被正确打包进rootfs

排查步骤

  1. 检查 project-spec/configs/rootfs_config 是否包含 CONFIG_helloworld=y
  2. 查看构建日志中是否有 helloworld.do_install 成功执行
  3. 进入 build/tmp/work/.../image/ 目录,检查 /bin/ 下是否存在 helloworld

❌ 问题3:串口无输出或乱码

现象 :屏幕一片空白,或显示乱码字符

可能原因
- 波特率不对(应为115200)
- 串口设备选错(不是ttyPS0?)
- 设备树中stdout-path配置错误

修复方式

编辑 system-user.dtsi ,确保有:

chosen {
    bootargs = "console=ttyPS0,115200 earlyprintk";
    stdout-path = "serial0:115200";
};

❌ 问题4:Permission denied

现象 ./helloworld 提示权限不足

原因 :文件未设置可执行位

解决 :在 .bb 文件的 do_install() 中明确加权限:

install -m 0755 helloworld ${D}${bindir}/

工程最佳实践建议

为了让你的PetaLinux项目更健壮、易维护,记住这几条黄金法则:

✅ 分离关注点:不要修改默认层

所有自定义内容放在 project-spec/meta-user/ 下,避免污染原始配置。

✅ 启用调试功能

开发阶段可在 petalinux-config 中开启:
- KERNEL_ENABLE_DEBUG_SHELL=y
- ROOTFS_INIT_MANAGER=busybox (轻量级init)

✅ 外部源码管理

大型项目建议将源码放在工程外,通过 SRC_URI = "git://..." file://../../src/hello.c" 引用。

✅ 启用缓存加速

配置sstate-cache和distcc可显著提升后续构建速度,尤其适合团队协作。

✅ 版本控制策略

.gitignore 推荐忽略:

build/
components/
tmp/
downloads/

只提交工程配置和自定义代码。


从Hello World出发,你能走多远?

也许你会说:“这不过是个打印程序而已。”

但请别小看它。这个简单的 helloworld 背后,是一整套现代嵌入式Linux开发范式的体现:

  • 自动化构建流程
  • 软硬件协同设计
  • 模块化应用管理
  • 可复现的部署机制

在此基础上,你可以轻松拓展出更复杂的功能:

🔹 驱动开发 :为PL侧IP编写UIO驱动,实现内存映射访问
🔹 数据交互 :通过AXI DMA实现高速数据搬运
🔹 边缘AI :集成Vitis AI库,在FPGA上跑YOLO推理
🔹 远程升级 :构建基于HTTP/MQTT的FOTA系统
🔹 混合系统 :在Zynq UltraScale+ MPSoC上运行Linux + FreeRTOS双系统

甚至未来还可以接入ROS 2、Kubernetes Edge、ZeroMQ等现代架构,打造真正的智能边缘节点。


写在最后

技术的学习从来不是一蹴而就。每一个老练的嵌入式工程师,都曾坐在电脑前盯着串口终端,等待那一行“Hello World”的出现。

今天,你做到了。

这不是终点,而是一个起点。

当你下次面对一块新的Zynq板子,或是接手一个复杂的SoC项目时,你会想起这个夜晚——你是如何一步步从零开始,亲手构建出一个能运行的嵌入式Linux系统的。

而这一切,始于一个最简单的程序。

“所有伟大的旅程,都始于一句‘Hello World’。”

如果你在实现过程中遇到了其他挑战,欢迎在评论区分享讨论。我们一起把这条路走得更稳、更远。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐