2. 搭建可复现的Zynq Linux驱动开发环境
说实话,很多刚接触Zynq的朋友,第一步就卡在PetaLinux工程创建上。不是工具不会用,而是对整个流程缺乏一个全局认知。今天我就带你走一遍完整的创建与配置流程,把我这些年踩过的坑、总结的经验都抖出来。
2.1 PetaLinux工程创建流程
创建PetaLinux工程,说白了就是告诉工具:我要为哪个硬件平台做系统,内核用什么版本,文件系统要多大。整个过程分三步走。
核心流程:硬件描述(XSA)→ 创建工程 → 配置子系统 → 编译生成
2.1.1 准备工作:获取硬件描述文件
在Vivado中完成硬件设计后,你需要导出硬件描述文件(XSA)。这个文件包含了Zynq处理器的配置信息,比如DDR大小、外设接口、时钟频率等。
# Vivado Tcl Console中执行
write_hw_platform -fixed -include_bit -force zynq_hw.xsa
我个人习惯在导出前,先检查一下硬件配置是否正确。曾经有一次,我忘了勾选UART1的MIO分配,结果系统启动后串口没输出,排查了半天才发现是硬件描述文件的问题。
2.1.2 创建PetaLinux工程
拿到XSA文件后,就可以创建PetaLinux工程了。这里我建议用命令行方式,比GUI更可控。
# 设置PetaLinux环境
source /opt/Xilinx/PetaLinux/2023.1/settings.sh
# 创建工程
petalinux-create --type project --template zynq --name my_zynq_project
# 导入硬件描述
cd my_zynq_project
petalinux-config --get-hw-description ../zynq_hw.xsa
执行petalinux-config后,会弹出配置菜单。这里有几个关键项需要你注意:
| 配置项 | 说明 | 我的建议 |
|---|---|---|
| Subsystem AUTO Hardware Settings | 自动检测硬件配置 | 保持默认,除非你有特殊需求 |
| Memory Settings | DDR大小、地址映射 | 与Vivado工程保持一致 |
| Boot Options | 启动方式(QSPI/SD卡/Flash) | 开发阶段选SD卡,量产选QSPI |
| U-Boot Configuration | U-Boot相关设置 | 默认即可,后续可单独配置 |
小技巧:第一次配置时,建议把Subsystem AUTO Hardware Settings -> Advanced bootable images storage settings中的boot image settings设为primary sd,这样调试阶段会方便很多。
2.2 内核配置:裁剪你的Linux
内核配置是PetaLinux工程中最灵活也最容易被忽视的环节。默认配置会包含大量你不需要的驱动,导致镜像臃肿、启动缓慢。
2.2.1 进入内核配置界面
petalinux-config -c kernel
这会打开一个基于menuconfig的内核配置界面。嗯,这里要注意,配置项非常多,但你不必全部看完。我一般只关注三类配置:
- 驱动相关:确保你硬件上用到的外设驱动被选中
- 文件系统支持:比如ext4、FAT、NFS等
- 调试功能:开发阶段开启,量产时关闭
2.2.2 关键配置项
以Zynq-7000系列为例,以下是我常用的配置路径:
| 功能 | 配置路径 | 说明 |
|---|---|---|
| UART驱动 | Device Drivers -> Character devices -> Serial drivers -> Xilinx UART | 串口通信必备 |
| SPI驱动 | Device Drivers -> SPI support -> Xilinx SPI controller | SPI外设通信 |
| I2C驱动 | Device Drivers -> I2C support -> Xilinx I2C controller | I2C外设通信 |
| GPIO驱动 | Device Drivers -> GPIO Support -> Xilinx GPIO | 通用GPIO控制 |
| 网络驱动 | Device Drivers -> Network device support -> Ethernet driver support -> Xilinx EMAC | 以太网通信 |
避坑指南:我曾经在配置内核时,为了省空间把CONFIG_EXT4_FS去掉了,结果根文件系统挂载失败,系统直接panic。所以,文件系统相关的配置一定要谨慎,建议先保持默认,确认能启动后再逐步裁剪。
2.3 根文件系统配置:选对方案事半功倍
根文件系统(RootFS)决定了你的Linux系统能跑什么应用。PetaLinux支持多种根文件系统类型,我根据项目经验整理了一个对比表:
| 类型 | 大小 | 灵活性 | 适用场景 |
|---|---|---|---|
| initramfs | 小(几MB) | 低 | 快速启动、内存运行 |
| SD卡ext4 | 大(GB级) | 高 | 开发调试、原型验证 |
| NFS网络挂载 | 取决于服务器 | 极高 | 驱动开发、频繁修改 |
| Yocto自定义 | 可定制 | 最高 | 量产产品、定制化需求 |
2.3.1 配置根文件系统
petalinux-config -c rootfs
在配置界面中,你可以选择预置的根文件系统模板,也可以手动添加软件包。我个人习惯在开发阶段选择petalinux-image-minimal,然后根据需要添加包:
- 开发工具:gcc、gdb、make、vim
- 网络工具:openssh、curl、wget、iperf
- 调试工具:strace、ltrace、perf、devmem2
- 文件系统工具:e2fsprogs、dosfstools
经验之谈:如果你在做驱动开发,强烈建议在根文件系统中加入devmem2和i2c-tools。这两个工具能帮你快速验证硬件寄存器读写是否正确,省去反复编译内核的麻烦。
2.4 设备树生成:硬件与软件的桥梁
设备树(Device Tree)是Zynq平台Linux驱动开发的核心。它描述了硬件资源如何映射到Linux内核。PetaLinux会根据你导入的XSA文件自动生成设备树,但往往需要手动调整。
2.4.1 设备树文件结构
在PetaLinux工程中,设备树文件位于project-spec/meta-user/recipes-bsp/device-tree/files/目录下。主要包含:
- system-user.dtsi:用户自定义设备树片段,用于添加或覆盖硬件节点
- pl.dtsi:PL(可编程逻辑)部分生成的设备树,由Vivado自动生成
- pcw.dtsi:PS(处理系统)部分配置生成的设备树
2.4.2 手动添加设备节点
假设你在PL中添加了一个自定义的AXI GPIO外设,地址为0x40000000,需要在设备树中这样描述:
// system-user.dtsi
/include/ "system-conf.dtsi"
/ {
my_gpio: gpio@40000000 {
compatible = "xlnx,xps-gpio-1.00.a";
reg = <0x40000000 0x10000>;
#gpio-cells = <2>;
gpio-controller;
xlnx,gpio-width = <32>;
};
};
&amba {
my_gpio: gpio@40000000 {
compatible = "xlnx,xps-gpio-1.00.a";
reg = <0x40000000 0x10000>;
#gpio-cells = <2>;
gpio-controller;
xlnx,gpio-width = <32>;
};
};
注意:设备树中的reg属性必须与Vivado中的地址分配一致。我曾经因为地址写错了一位,导致驱动加载时ioremap失败,系统直接oops。排查了整整一天才发现是设备树的问题。
2.5 知识体系总览
为了让你对整个流程有个直观的认识,我画了一张流程图:
2.6 编译与验证
所有配置完成后,执行编译命令:
petalinux-build
编译成功后,生成的文件在images/linux/目录下:
- image.ub:包含内核、设备树、根文件系统的统一镜像
- BOOT.BIN:包含FSBL、U-Boot、bitstream的启动镜像
- system.dtb:编译后的设备树二进制文件
验证方法:将BOOT.BIN和image.ub拷贝到SD卡,插入Zynq开发板,上电后通过串口观察启动日志。如果看到VFS: Mounted root (ext4 filesystem) on device 179:2,说明你的系统已经成功启动了。
好了,以上就是PetaLinux工程创建与配置的完整流程。从硬件描述到系统启动,每一步都有它的意义。你可能会觉得步骤有点多,但相信我,当你第一次看到自己的Zynq板子打印出Linux启动信息时,那种成就感会让你觉得一切都值得。