起因

EBAZ4205 是翼比特(EBIT)的 ZYNQ 7010 矿板,矿难后二手价极低,ZYNQ 双核 ARM + FPGA 可编程逻辑都在,拿来学 FPGA 和嵌入式 Linux 很划算。要在它上面跑 PYNQ(Python 驱动 FPGA 的框架),官方镜像只认官方板卡,杂牌板必须用 PYNQ 的 sdbuild 工具流为自己的硬件出一份镜像。此文章记录使用矿板搭建环境的步骤,和解决其中的问题。

需求

  • 为 EBAZ4205(ZYNQ-7010)制作 PYNQ v2.4 的可启动 SD 卡镜像
  • 复用官方预编译 rootfs,只重做和硬件相关的引导部分(省时间)

技术实现原理

镜像里有什么:ZYNQ 的启动链条

做出来的 SD 卡镜像 = 两个分区:FAT 引导分区(放 BOOT.BIN 等)+ ext4 根文件系统分区(Ubuntu)。ZYNQ 上电后片内 BootROM 从 SD 卡引导分区读 BOOT.BIN → BOOT.BIN 里的 FSBL 初始化 DDR、时钟 → u-boot 接手加载内核与设备树 → 挂载 rootfs 启动 Ubuntu,PYNQ 的 Python 环境全在 rootfs 里。理解这条链,就知道制作过程要准备的三样原料各管哪一段。

三样原料:bit、hdf、prebuilt rootfs

  • base.bit:FPGA 侧的电路,Vivado 工程综合实现后生成,最终进 BOOT.BIN;
  • system.hdf:硬件描述文件,记录 PS 侧配置(DDR 型号、外设、地址映射),PetaLinux 拿它生成 FSBL 和设备树——bit 和 hdf 必须出自同一个 Vivado 工程,不然 FPGA 电路和软件看到的硬件对不上;
  • bionic.arm.2.4.img:官方预编译的 Ubuntu rootfs。自制板卡不必重编 rootfs(那需要 qemu + 交叉工具链从头构建,非常耗时),Makefile 直接复用预编译镜像,只重建与硬件绑定的引导部分——这是 sdbuild 流程省时间的核心设计,也是要准备 prebuilt 目录的原因。

boards/zynq7010/ 板卡目录就是告诉 sdbuild“这块板叫什么、bit 在哪、hdf 在哪”:.spec 描述板名和 bitstream 路径,petalinux_bsp/hardware_project 放 hdf,sdbuild 据此调用 PetaLinux 生成 BSP(FSBL + u-boot),再和 rootfs 拼成完整镜像。

为什么有一堆“魔改”步骤

  • 切 bash:PetaLinux/PYNQ 的脚本大量使用 bash 语法,而 Ubuntu 的 /bin/sh 默认是 dash,语法不兼容会直接报错;
  • 改 newlib.sh 下载地址:脚本里写死的老镜像源已失效,手工换成可用的源;
  • 删 Makefile 里 sdx 检查:本机没装 SDx 环境,检查过不去就删掉检查(不影响本流程);
  • make 前先 sudo -:以完整登录环境进 root,PATH 才带得上 /opt 里装的工具链,否则 checkenv 一步就报错。

制作步骤

1、使用VMware搭建Ubuntu16.04版本的虚拟机,一定要注意虚拟机内存至少4G左右,否则后面会出现很多问题。

shell切换到bash

1
sudo dpkg-reconfigure dash 选NO

2、根据网上教程安装 petalinux2018.3 Vivado2018.3 。其中Vivado里面会包含SDK。这两个安装到哪个目录下都行,我一般安装到 /home/user/ 目录下。

有人喜欢安装到 /opt 目录下,安装到这个目录下,需要注意先改变 /opt 是属性再安装。

1
sudo chown -R $USER:$USER /opt

3、准备 .bit和 .hdf文件,这个两个文件是利用Windows的Vivado中 Run Block Automation 生成的。并把这两个文件改名为system.hdf base.bit备用。

4、把PYNQ先从github上面下载下来

1
2
3
4
git clone -b v2.4 https://github.com/Xilinx/PYNQ.git
cd PYNQ
git checkout v2.4
git checkout -b zynq7010  

从2.4分支上再创建一个新分支,有问题可以倒退回去。

把pynq_rootfs_arm_v2.4.zip文件系统下载下来备用

https://www.xilinx.com/member/forms/download/xef.html?filename=pynq_rootfs_arm_v2.4.zip

5、进入/PYNQ/sdbuild/scripts/ 执行./setup_host.sh 把qemu和crosstool-ng下载下来,默认下载到/opt 目录

进入文件夹 /opt/crosstool-ng/lib/crosstool-ng-1.22.0/scripts/build/libc/ 打开文件newlib.sh

"{http://mirrors.kernel.org/sourceware/newlib,ftp://sourceware.org/pub/newlib}"

去掉花括号 改为 "http://mirrors.kernel.org/sourceware/newlib”

6、执行环境变量

1
2
3
sudo vi  ~/.bashrc   
export PATH=/opt/qemu/bin:/opt/crosstool-ng/bin:$PATH
source ~/.bashrc 

再执行

1
2
3
petalinux/2018.3/settings.sh
Vivado/2018.3/settings64.sh
SDK/2018.3/settings64.sh

7、由于没有安装SDx环境,所用进入 /PYNQ/sdbuild/ 文件夹,打开Makefile 删除 which sdx | fgrep ${KERNEL_VERSION}

8、在 /PYNQ/sdbuild/ 目录下新建文件夹 ‘prebuilt’ 将bionic.arm.2.4.img文件拷贝至该文件夹 在 /PYNQ/boards/ 目录下新建文件夹 zynq7010 在 zynq7010 中再新建两个文件夹分别为 base 和petalinux_bsp 在 petalinux_bsp 中再建立文件夹 hardware_project 分别将base.bit拷贝到base;system.hdf拷贝到hardware_project zynq7010目录下新建zynq7010.spec 打开zynq7010.spec,修改内容如下:

1
2
3
4
5
        ARCH_${BOARDS} := arm
        BSP_${BOARDS} := 
        BITSTREAM_${BOARDS} := base/base.bit

        STAGE4_PACKAGES_Pynq-Z2 := pynq  ethernet

9、在make 前先执行 sudo - 操作,否则make的话 会出现错误。checkenv 的时候错误

1
        make BOARDS=zynq7010  PREBUILT=./prebuilt/bionic.arm.2.4.img

如make出现错误,解决后先执行make clean后,再进行make

10、等2个小时左右就编译完成了。

烧写 SD 卡

烧写就是把 output 下生成的 .img 原样写进卡:镜像自带分区表,写完卡上就是“FAT 引导分区 + ext4 rootfs”的成品结构。

/sdbuild/output 目录下生成的.img复制至Windows 使用 Win32DiskImager将镜像烧写至SD卡(至少8g)上

或者Linux下使用dd命令烧写

sudo dd if=<PYNQ>/sdbuild/output/<rootfs.img> of=/dev/sdb bs=4M

踩坑记录与注意事项

  • 虚拟机内存至少 4G:PetaLinux 编译阶段吃内存,不够会中途死掉或报一堆莫名错误——步骤 1 强调的原因;
  • make 出错后先 make clean 再重试:增量构建会保留出错时的中间状态,带着旧状态重跑大概率原地复现;
  • bit 与 hdf 必须同工程同期生成:PS 配置、设备树和 FPGA 电路不一致时能编过但板子起不来,排查极难;
  • SD 卡至少 8G:镜像写完 rootfs 分区还要留扩容空间,小卡连写都写不完;
  • dd 的 of 写全盘设备不是分区:of=/dev/sdb 是整卡,写成 /dev/sdb1 会把分区表落在分区里、卡不可启动;写错盘会毁掉目标盘数据,执行前核对设备名;
  • hdf 里 DDR 型号与实际板子不符:FSBL 按 hdf 初始化 DDR,型号不对内存初始化就失败,串口连输出都没有。