在FPGA zcu102上复现LvNA项目 (LvNA Reproduction on FPGA zcu102 Board)

LvNA是国内一个基于Rocket Chip的RISC-V核项目, 为处理器设计和开发提供方便的仿真和上板支持, 跳转链接. 本文将介绍如何在FPGA zcu102上复现LvNA项目, 前半部分是上板步骤, 后面列举了复现时本人遇到的问题, 希望帮助后来的同学缩短调试时间. 文章基于官方提供的上板指导, 和另一位同学的复现指南. 但因为本人的使用环境和已有的两份指导不完全一致, 直接照搬官方指导无法上板, 造成了一些困惑和麻烦, 因此有必要记录本人的详细环境, 遇到的问题和解决办法, 仅供参考.

本文和已有指南的区别及简单原因

官方指南系统性描述了上板步骤, 但是在fpga/boot/README.md里的步骤里, 由用户下载并编译ATF, FSBL和u-boot, 可能因为嵌入的脚本和最新的板子型号对不上, 经测试无法成功上板, 会出现Flash型号识别失败SF: unrecognized JEDEC id bytes, 详细见常见问题#1. 所以本文采用了Xilinx更推荐的PetaLinux对boot镜像和Linux进行编译和打包, 以避免脚本无法对应的问题.

尤同学的复现指南和本文在环境上有一些区别: 1) 前人复现指南的部分命令基于WSL, 本文的工作机器为Linux环境, 上板串口连接mac机器. 不同的环境并不会造成很大区别. 2) 前人复现指南没有将bitstream放入FSBL, 需要手动加载, 本文使用PetaLinux自动打包后可以直接进入Linux环境. 3) 另外, 本文尽可能沿用了LvNA官方的prm-sw仓库进行RISCV subsystem通信.

环境说明

平台和软件

  • LvNA项目commit最新版: (Labeled-RISC-V) f6895ab. (prm-sw) 0f655a9.
  • Xilinx Vivado 2019.1
  • Xilinx PetaLinux 2019.2 (经测试, 2019.1的PetaLinux无法编译上板, 请查看常见问题#2)
  • zcu102 BSP v2019.2
  • 工作环境 Ubuntu 18.04 (运行LvNA仿真, Vivado综合, PetaLinux编译)
  • 串口调试环境 macOS Monterey 12.5.1

硬件

  • FPGA zcu102开发版, rev1.1

步骤

1. 确认LvNA仿真和综合复现成功

请按照LvNA官方README操作, 执行到Run with FPGA结束, 成功生成bitstream, 路径在fpga/board/zcu102/build/<yourname>-zcu102/<yourname>-zcu102.runs/impl_1/system_top.bit, 后文称<path-to-bitstream>.

2. SD Card文件准备

请使用本文步骤代替官方boot/README.md.

激活PetaLinux环境,确认没有再要求安装更多的包.

source <path-to-petalinux>/settings.sh

使用PetaLinux创建一个新的boot工程:

petalinux-create -t project -n <yourname> -s <path-to-zcu102-bsp>/xilinx-zcu102-v2019.2-final.bsp

进入Vivado, 生成硬件描述文件: File -> Export -> Export Hardware… 无需勾选Include bitstream. 对于2019.1版本, 生成的文件路径<yourname>-zcu102.sdk/system_top.hdf. 对于2019.2版本, 生成的文件为XSA, 请按照此部分转换为hdf.

进入工程目录, 导入hdf配置:

cd <yourname>

petalinux-config --get-hw-description=<yourname>-zcu102.sdk/

注意只需要精确到sdk所在目录的路径.

配置过程中会弹出选项, 请按照如下配置:

  • select Image Packaging Configuration -> Root filesystem type (EXT (SD/eMMC/QSPI/SATA/USB))
  • unchosen Image Packaging Configuration -> Copy final images to tftpboot

配置linux kernel:

petalinux-config -c kernel

配置过程中会弹出选项, 请按照如下配置:

  • unchose General setup -> Initial RAM filesystem and RAM disk (initramfs/initrd) support
  • unchose Kernel hacking -> Filter access to /dev/mem

导入PS端LvNA额外的device tree blob配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
/ {
chosen {
bootargs = "root=/dev/mmcblk0p2 rootfstype=ext4 rootwait earlycon clk_ignore_unused cpuidle.off=1 console=ttyPS0,115200";
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;

mem_reserved: buffer@800000000 {
reg = <0x00000008 0x00000000 0x0 0x80000000>;
};
// ultraZ only has 2GB memory for PS, change the setting above accordingly
};
};

编译Linux kernel:

petalinux-build

打包BOOT.BIN:

petalinux-package --boot --format BIN --fsbl images/linux/zynqmp_fsbl.elf --u-boot --fpga <path-to-bitstream>

将images/linux目录下的BOOT.BINimage.ub拷贝到SD卡的第一个分区.

3. 准备SD卡第二个分区

这部分请参考官方指导.

请注意本文在qemu-debootstrap指令时遇到segmentation fault, 需切换到非最新版debian, 例如:

sudo qemu-debootstrap --arch arm64 buster /mnt http://ftp.debian.org/debian

4. 串口调试 (PS boot)

确保SD卡已经按照上述步骤准备好:

  • 分区1 (mmcblk0p1或sdb1或其他名字), FAT文件系统, 包含BOOT.BIN和image.ub.
  • 分区2 (mmcblk0p2或sdb2或其他名字), EXT4文件系统, 包含debian rootfs.

插入SD卡, 调整FPGA板到boot mode, 参考. 或者从官方指导Set your board to SD boot mode这里继续.

准备串口连接的驱动:

https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers

连接USB线从FPGA J83口到macOS, 通过ls /dev/tty.*查看串口设备名, 例如/dev/tty.SLAB_USBtoUART. 一共有四个设备, 出现boot log的设备名随机. 本人设备表为

1
2
ls /dev/tty.SLAB_USBtoUART*
/dev/tty.SLAB_USBtoUART /dev/tty.SLAB_USBtoUART4 /dev/tty.SLAB_USBtoUART5 /dev/tty.SLAB_USBtoUART6

串口的波特率为115200. mac端访问方式如下:

请确保按照官方指导, 可以访问PS部分的debian Linux, 正确的boot log串口输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
Xilinx Zynq MP First Stage Boot Loader
Release 2019.2 Sep 15 2022 - 07:26:54
NOTICE: ATF running on XCZU9EG/silicon v4/RTL5.1 at 0xfffea000
NOTICE: BL31: Secure code at 0x0
NOTICE: BL31: Non secure code at 0x10080000
NOTICE: BL31: v2.0(release):xilinx-v2019.1-12-g713dace9
NOTICE: BL31: Built : 07:24:40, Sep 15 2022
PMUFW: v1.1


U-Boot 2019.01 (Sep 15 2022 - 07:25:42 +0000)

Model: ZynqMP ZCU102 Rev1.0
Board: Xilinx ZynqMP
DRAM: 4 GiB
EL Level: EL2
Chip ID: zu9eg
MMC: mmc@ff170000: 0
Loading Environment from FAT... *** Warning - bad CRC, using default environment

In: serial@ff000000
Out: serial@ff000000
Err: serial@ff000000
Model: ZynqMP ZCU102 Rev1.0
Board: Xilinx ZynqMP
Bootmode: LVL_SHFT_SD_MODE1
Reset reason: EXTERNAL
Net: ZYNQ GEM: ff0e0000, phyaddr c, interface rgmii-id

Warning: ethernet@ff0e0000 MAC addresses don't match:
Address in ROM is 01:02:03:04:05:06
Address in environment is 00:0a:35:00:22:01
eth0: ethernet@ff0e0000
U-BOOT for xilinx-zcu102-2019_2

ethernet@ff0e0000 Waiting for PHY auto negotiation to complete..........

Device: mmc@ff170000
Manufacturer ID: 3
OEM: 5344
Name: SB16G
Bus Speed: 187481250
Mode : UHS SDR104 (208MHz)
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 14.8 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
63008056 bytes read in 4226 ms (14.2 MiB/s)
## Loading kernel from FIT Image at 10000000 ...
Using 'conf@system-top.dtb' configuration
Trying 'kernel@1' kernel subimage
Description: Linux kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x10000108
Data Size: 18082304 Bytes = 17.2 MiB
Architecture: AArch64
OS: Linux
Load Address: 0x00080000
Entry Point: 0x00080000
Hash algo: sha1
Hash value: 9a1a6dc514e028d678da04a1713cfe8ffebaa9ef
Verifying Hash Integrity ... sha1+ OK
## Loading ramdisk from FIT Image at 10000000 ...
Using 'conf@system-top.dtb' configuration
Trying 'ramdisk@1' ramdisk subimage
Description: petalinux-user-image
Type: RAMDisk Image
Compression: gzip compressed
Data Start: 0x1114985c
Data Size: 44879689 Bytes = 42.8 MiB
Architecture: AArch64
OS: Linux
Load Address: unavailable
Entry Point: unavailable
Hash algo: sha1
Hash value: 447a5a0d69e59eb70cc13fae7d8ae2b5b7e27462
Verifying Hash Integrity ... sha1+ OK
## Loading fdt from FIT Image at 10000000 ...
Using 'conf@system-top.dtb' configuration
Trying 'fdt@system-top.dtb' fdt subimage
Description: Flattened Device Tree blob
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x1113ec0c
Data Size: 43913 Bytes = 42.9 KiB
Architecture: AArch64
Hash algo: sha1
Hash value: 761e4c91053bfb5754206eba17f8be4ace42158f
Verifying Hash Integrity ... sha1+ OK
Booting using the fdt blob at 0x1113ec0c
Loading Kernel Image ... OK
Loading Ramdisk to 76533000, end 78ffff49 ... OK
Loading Device Tree to 0000000007ff2000, end 0000000007fffb88 ... OK

Starting kernel ...

[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 4.19.0-xilinx-v2019.2 (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 SMP Fri Oct 25 08:23:52 UTC 2019
[ 0.000000] Machine model: ZynqMP ZCU102 Rev1.0
...

PS端账号名和密码均为root.

请确保PS端使用SD卡第二分区的文件系统, 而非initramfs. 只有前者可以在SD卡上保存文件更改.

5. 串口调试 (PL boot)

请提前准备prm-sw代码, 放到debian分区的/home/root目录下.

prm-sw有一处dtb内容需修改, 补充以下内容, 完整文件请参考(https://github.com/Gallium70/labeled-RISC-V-boot/blob/main/zcu102.dts)

1
2
3
4
5
serial@60000000 {
compatible = "sifive,uart0";
reg = <0x00 0x60000000 0x00 0x1000>;
reg-names = "control";
};

可以按照官方教程操作, SMP boot试验成功.

常见问题

1. 按照官方LvNA boot教程 PS boot提示Flash型号识别失败SF: unrecognized JEDEC id bytes

请按照本文使用PetaLinux生成BOOT.BIN文件.

2. 使用PetaLinux生成的BOOT.BIN, boot log卡在FSBL两行.

请检查PetaLinux和bsp版本, 使用2019.2

3. PetaLinux使用提示ERROR: Failed to generate meta-plnx-generated layer

详细的错误报告在build/config.log中, 请检查是否缺少依赖.

如果不是依赖缺失, 可以尝试换用python2.0环境. 使用virtualenv创建python2.0环境, 并使用source命令进入环境再执行petalinux命令.

4. PL启动时提示init_mmap failed

请确保petalinux-config -c kernel配置时去掉勾选Filter access to /dev/mem.

5. riscv-linux fpga_defconfig编译失败

可以移除initramfs.txt里不需要的库, 比如zlib, redis, …

profile直接sudo copy进来,改chmod 755.

6. PL boot时找不到串口端口/dev/ttyUL1.

petalinux-config配置时确保没有勾选 DTG settings ->Remove PL from devicetree.

7. PL boot log在SMP部分挂住

请检查LvNAConfig.scala里的core数量要和PL dtb里的一致.

更多问题, 欢迎讨论.

---以上---