本文档记录了我在使用 Petalinux 工具进行 Linux 系统制作与SD卡启动过程中遇到的关键问题与解决方案
首次执行 petalinux-config --get-hw-description=... 时出现:
error loading hsi package: couldn't load file "libxv_commontasks.so"
libtinfo.so.5: cannot open shared object file
Ubuntu 22.04 缺少 PetaLinux 2023.2 所需的兼容库:
sudo apt update
sudo apt install libtinfo5
安装后重新导入 XSA 即可,不需要重建工程。
将 BOOT.BIN、boot.scr 和 image.ub 放入 SD 卡后,上电没有任何串口输出。最初怀疑设备树或 SD 卡未制作正确。
使用旧裸机 BOOT.BIN 验证,确认串口、SD0启动拨码和BootROM读卡正常。
检查SD卡为MBR分区表,第一分区为FAT32。
对比Ubuntu归档文件与SD卡文件的SHA-256,排除复制错误。
Get-FileHash D:\BOOT.BIN -Algorithm SHA256
问题不在设备树。设备树要到 U-Boot/Linux 阶段才会使用;完全无输出应先检查启动模式、BOOT.BIN和FSBL早期初始化。
XFSBL_PSU_INIT_FAILED
================= In Stage Err ============
Fsbl Error Status: 0x0
这说明 BootROM 已经读取并运行 FSBL,但 FSBL 在 PS 初始化阶段失败,尚未进入 U-Boot 和 Linux。
使用早期 demo_platform 生成的 Vitis FSBL 重新打包后,可以继续进入 U-Boot。由此一度怀疑 PetaLinux FSBL 生成有问题。
后续事实证明,这只是旧 Platform 残留初始化文件造成的“偶然可启动”,并非最终解决方案。
image.ub时SD传输超时Vitis旧FSBL进入U-Boot后出现:
sdhci_transfer_data: Transfer data timeout
Error reading cluster
Unable to read file image.ub
U-Boot能读取较小的boot.scr,但读取约34 MiB的image.ub时稳定超时。后续Bad FIT等信息均为连锁错误。
在 system-user.dtsi 中限制SD0频率:
&sdhci0 {
max-frequency = <25000000>;
disable-wp;
};
max-frequency解决大文件读取不稳定;
disable-wp解决Linux将SD卡识别为只读的问题。
修复后U-Boot成功读取并校验image.ub:
35261796 bytes read in 4032 ms (8.3 MiB/s)
Verifying Hash Integrity ... sha256+ OK
Starting kernel ...
nwl-pcie fd0e0000.pcie: host bridge ...
rcu: INFO: rcu_sched detected stalls
Workqueue: events_unbound deferred_probe_work_func
临时在设备树中禁用PCIe:
&pcie {
status = "disabled";
};
禁用后Linux完整启动,证明SD、DDR、内核和rootfs基本正常,故障集中在PCIe/SerDes层。
psu_init.c旧Platform的FSBL可以启动DDR和Linux,但GTR状态不正确;启用PCIe后Linux发生RCU stall。
demo_platform最初由早期XSA创建,后来虽然切换了XSA,但实际参与FSBL编译的psu_init.c仍是旧文件,其中SerDes初始化为空。
旧FSBL初始化DDR
→ 未初始化PCIe SerDes
→ Linux仍探测PCIe
→ RCU stall
新建Platform并检查psu_init.c是否包含GTR初始化,例如搜索:
Select-String -Path "<Platform>\zynqmp_fsbl\psu_init.c" -Pattern "0XFD4023E4"
但新Platform生成的完整FSBL在冷启动时又出现PS初始化失败,说明还存在更早的硬件配置问题。
为区分DDR和SerDes,先后测试了调试版、SerDes重试版和阶段诊断版FSBL。
最终关键输出为:
#PSU_INIT_DIAG mio=1 pre=1 pll=1 clk=1 ddr=1 phy=0 \
periph=1 serdes=1 pwrdown=1 afi=1 fail=0x20
该结果说明:
SerDes已经通过:serdes=1;
DDR控制器配置完成:ddr=1;
DDR PHY训练失败:phy=0、fail=0x20。
因此,“PCIe直接导致DDR失败”和“PetaLinux FSBL不可用”的判断均被排除,排查重点转回XSA中的DDR参数。
参数 | 正确配置 | 错误配置 |
|---|---|---|
DRAM IC Bus Width | 16 Bits | 8 Bits |
DRAM Device Capacity | 8192 Mbits | 2048 Mbits |
Row Address Count | 16 | 14 |
Bank Group Address Count | 1 | 2 |
Effective DRAM Bus Width | 64 Bit | 64 Bit |
错误配置假设了与核心板实际DDR完全不同的颗粒组织,进而改变地址映射、刷新周期和PHY训练参数,最终导致FSBL在DDR PHY阶段失败。
在Vivado中恢复:
Memory Type DDR4
Requested Device Frequency 800 MHz
Speed Bin DDR4-1600J
Effective DRAM Bus Width 64 Bit
DRAM IC Bus Width 16 Bits
DRAM Device Capacity 8192 Mbits
Row Address Count 16
Bank Group Address Count 1
Bank Address Count 2
Column Address Count 10
ECC Disabled
重新综合、实现、生成bitstream并导出新XSA:
PL2SSD20260630.xsa
SHA-256: da961da3ebe27012c5c739e49b7fcf1b1da4095e1d68d14ea7edf3f7f253d955
将新XSA更新到现有PetaLinux工程后重新编译。此时PetaLinux自己生成的zynqmp_fsbl.elf即可正常启动,最终证明问题根源是旧XSA,而不是PetaLinux工具。
先保持PCIe禁用完成基础启动验证,再删除:
&pcie {
status = "disabled";
};
重新构建后的结果:
不插SSD:Link is DOWN,Linux继续启动
插入SSD:Link is UP,SSD成功枚举
RCU stall不再出现,说明修正后的XSA、FSBL和PCIe SerDes初始化均正常。
/dev/nvme0n1nwl-pcie fd0e0000.pcie: Link is UP
pci 0000:01:00.0: [1e4b:1202] type 00 class 0x010802
但:
# CONFIG_BLK_DEV_NVME is not set
PCIe链路和SSD枚举已经成功,但Linux内核没有NVMe块设备驱动。
cd ~/DDAQ/01_petalinux/ddaq_linux
petalinux-config -c kernel
启用:
Device Drivers
→ NVME Support
→ <*> NVM Express block device
目标配置:
CONFIG_BLK_DEV_NVME=y
重新编译并更新image.ub后出现:
/dev/nvme0 # NVMe控制器
/dev/nvme0n1 # 实际存储Namespace
SSD最终以PCIe Gen2 ×4完成驱动绑定和ext4挂载。
本文章使用limfx的vscode插件快速发布