黑金AXU2CGB ZYNQ板子移植PYNQ

本文仅为踩坑记录,非完整教程

正常工作的外设:

0)系统可正确识别到双核A53以及2GB DDR4

1)千兆以太网通信正常(使用iper3进行内网测试,可跑到960mbps左右)

2)dp1.4接口输出正常,可支持到最高4K30hz RGB输出

3)4个USB3.0接口正常,测试过USB2.0的键鼠以及USB3.0的U盘

4)调试串口工作正常,115200 8n1

未测试的外设:

1)PCIE X1,无相应设备测试

2)MIPI CSI接口

3)按键(修改设备树能用?)

4)仅测试SD卡其他,EMMC启动未测试,能读取EMMC内容

编译命令记录

1、使用Ubuntu 18.04.4虚拟机,分配的CPU建议8核以上,内存建议16GB以上,硬盘建议200GB以上,建议使用全局科学,petalinux用的akamai cdn跟shit一样。

下载地址:https://old-releases.ubuntu.com/releases/18.04.4/ubuntu-18.04.4-desktop-amd64.iso

记得不要打开自动更新

2、根据黑金教程安装Vitis和petalinux全家桶

3、设置PYNQ环境

3.1 克隆PYNQ源码,由于黑金采用的是vivado 2020.1,这里配置对应的PYNQ版本v2.6

git clone https://github.com/Xilinx/PYNQ.git pynq_port
cd pynq_port
git checkout image_v2.6

这里贴上各个vivado版本对应的PYNQ版本

Release versionXilinx Tool Version
v1.42015.4
v2.02016.1
v2.12017.4
v2.22017.4
v2.32018.2
v2.42018.3
v2.52019.1
v2.62020.1
v2.72020.2
v3.02022.1

3.2 安装编译依赖,使用黑金的脚本(host_env_setup.sh)安装petelinux依赖

#!/bin/bash
set -x
script_dir=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd)
# This script sets up a Ubuntu host to be able to create the image by
# installing all of the necessary files. It assumes a host with
# passwordless sudo
# Install a bunch of packages we need
read -d '' PACKAGES <<EOT
iproute2
gcc
g++
net-tools
libncurses5-dev
zlib1g:i386
libssl-dev
flex
bison
libselinux1
xterm
autoconf
libtool
texinfo
zlib1g-dev
gcc-multilib
build-essential
screen
pax
gawk
python3
python3-pexpect
python3-pip
python3-git
python3-jinja2
xz-utils
debianutils
iputils-ping
libegl1-mesa
libsdl1.2-dev
ninja-build
pylint3
cpio
EOT
set -e
sudo apt-get update
if [[ $(lsb_release -rs) == "16.04" ]]; then
echo "Install packages on Ubuntu 16.04..."
sudo apt purge -y libgnutls-dev
elif [[ $(lsb_release -rs) == "18.04" ]]; then
echo "Install packages on Ubuntu 18.04..."
else
echo "Error: current OS not supported."
exit 1
fi
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y $PACKAGES
echo "Now install Vivado, SDK, and Petalinux."
echo "Re-login to ensure the enviroment is properly set up."

安装PYNQ依赖,脚本会用apt安装各种需要的包,以及下载QEMU和CrossTool-NG。

cd pynq_port/sdbuild/scripts
./setup_host.sh

3.3 设置环境变量,修改家目录下的.bashrc文件,该文件为隐藏文件,将下面几行命令加入到最后面。这样一来,就可以在命令行中运行这些软件了。

source /tools/Xilinx/Vivado/2020.1/settings64.sh
source /tools/Xilinx/Vitis/2020.1/settings64.sh
source /opt/pkg/petalinux/settings.sh
export PATH=/opt/qemu/bin:/opt/crosstool-ng/bin:$PATH

3.4 添加自定义开发板

下列内容转载自Haozhe Zhu的博客:EdgeBoard的PYNQ移植 - Haozhe Zhu's Blog

感谢!

PYNQ在boards文件夹下预置了Pynq-Z1Pynq-Z2ZCU104三个与对应开发板同名的文件夹。它们的内部结构大同小异,主要分成以下五个部分:

  1. notebooks
  2. petalinux_bsp
  3. packages
  4. baselogictoolsOverlay文件夹;
  5. <board_name>.spec

下面简单介绍下这些文件和文件夹的功能,具体的细节(如果你需要定制一些复杂的东西)还请自行阅读PYNQ的编译脚本源代码。

notebooks文件夹会原样复制到最终的用户目录下,每次大家打开Jupyter Notebook后看到的就是它。这个文件夹里的内容不是很重要,一般都是放些教程。

petalinux_bsp文件夹用于PetaLinux生成BSP,它只在sdbuild/scripts/create_bsp.sh脚本中用到。该文件夹里边包括两个文件夹meta-userhardware_project。其中,meta-user文件夹会被复制到PetaLinux项目文件夹下的project-spec/meta-user,里面放设备树文件、各种用户配置等(如果你对PetaLinux项目的目录结构不了解的话可以参考UG1144)。hardware_project里需要放.xsa硬件描述文件(该文件由Vivado导出),或者也可以放一些脚本(至少包括一个Makefile)供PetaLinux实时地生成.xsa文件。如果用户在<board_name>.spec中指定了BSP,那么hardware_project不会被用到。这里一个文档中一个没有注明的是,meta-user总是会起作用,即使你指定了BSP,它也会覆盖掉里边的meta-user并重新打包。

packages文件夹的结构和sdbuild/packages的结构类似,这两个目录下的每个文件夹对应一个个的组件,在编译过程中会被安装到RootFS中。安装过程主要是在sdbuild/scripts/install_packages.sh中进行。如果你需要增加组件,建议阅读此脚本和sdbuild/packages/README.md了解更多细节。

其他文件夹中如果存在Makefile文件,就会被认为是Overlay文件夹。在编译pynq本身时,<pynq_repo_dir>/build.sh脚本会试图进入这些文件夹,并挨个检查是否存在.bit.hwh.xsa等文件。这些文件夹不是必须的,主要是为用户提供一些针对该开发板的预置Overlay

<board_name>.spec文件描述了针对该开发板的各种配置和文件路径。它的格式如下所示:

ARCH_<board_name> := aarch64 # Zynq的CPU架构,可以是aarch64或arm
BSP_<board_name> := ... # 开发板的BSP文件(如果有的话)
BITSTREAM_<board_name> := ... # 默认的比特流文件
FPGA_MANAGER_<board_name> := 1

STAGE4_PACKAGES_<board_name> := pynq ethernet ...

注意这里的board_name要和文件夹的名字一致。

接下来我们可以依样画葫芦为自己的开发板配置这些文件了。

这里贴上我的spec文件

peta@peta:~/pynq_port/boards/Alinx$ cat Alinx.spec 
ARCH_Alinx := aarch64
BSP_Alinx := 
BITSTREAM_Alinx := base/base.bit
FPGA_MANAGER_Alinx := 1
STAGE4_PACKAGES_Alinx := xrt pynq ethernet

将vivado导出的xsa文件放置在对应的目录下,并且重命名为板子名字

peta@peta:~/pynq_port/boards/Alinx/petalinux_bsp/hardware_project$ ls
Alinx.xsa

如果需要自定义设备树,修改对应位置的system-user.dtsi文件

peta@peta:~/pynq_port/boards/Alinx/petalinux_bsp/meta-user/recipes-bsp/device-tree/files$ ls
system-user.dtsi

如果需要自定义U-Boot配置,修改对应位置的platform-top.h文件

peta@peta:~/pynq_port/boards/Alinx/petalinux_bsp/meta-user/recipes-bsp/u-boot/files$ ls
platform-top.h

下载xilinx官方预先编译好的pynq rootfs,避免重复编译

链接:http://www.pynq.io/board.html

我们用的是v2.6版本,下载对应版本:http://bit.ly/pynq_rootfs_aarch64_v2_6

得到pynq_rootfs_aarch64.zip,解压后得到bionic.aarch64.2.6.0_2020_10_19.img

放置在~/pynq_port/sdbuild/prebuild目录下

理论上,我们可以开始进行漫长的编译了,过程顺利的话,可以在output目录下得到相应的镜像

Alinx-2.6.0.img

cd ~/pynq_port/sdbuild
make BOARDS=Alinx PREBUILT=./prebuild/bionic.aarch64.2.6.0_2020_10_19.img

如果需要修改petalinux相关的配置,可以在第一次编译完成后,进入~/pynq_port/sdbuild/build/Alinx/petalinux_project目录下

运行

PYNQ_BOARDNAME=Alinx FPGA_MANAGER=1 petalinux-config -c kernel    #修改Linux内核配置
PYNQ_BOARDNAME=Alinx FPGA_MANAGER=1 petalinux-config -c u-boot    #修改u-boot配置
PYNQ_BOARDNAME=Alinx FPGA_MANAGER=1 petalinux-config -c rootfs    #修改rootfs配置

踩坑记录

1、内核在初始化SMP核心时卡死

这是在最开始学习移植petalinux时遇到的问题,最后发现是vivado在导出xsa时未选择包括bitstream导致的

2、无法从SD卡启动,找不到RootFS

这个是比较常见的错误,由于xilinx的工程师在开发pynq时写死了一些参数

Kernel Panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,10)

可能原因1:SD卡的写保护

在黑金的教程中,提供了修改设备树的方法,即使在block design内关闭了SD卡的WP,也要进行这项配置

/include/ "system-conf.dtsi"
/ {
};

/* SD */
&sdhci1 {
    disable-wp;
    no-1-8-v;
};

/* USB */
&dwc3_0 {
    status = "okay";
    dr_mode = "host";
};

可能原因2:设备树bootargs参数中设置了错误的root分区位置

PYNQ默认总是从/dev/mmcblk0(这个路径是PYNQ上的,不是你的宿主Ubuntu上的)启动系统,即它如果它有多个SD外设的话,SD卡要连在PS_SD0上。不幸的是,我这块黑金板子有两个SD设备,一个是一颗eMMC Flash芯片,另一个是我们的TF卡槽。eMMC 连在PS_SD0上,TF卡连在PS_SD1上。默认情形下,PYNQ总是会尝试从前者启动,而我们的系统实际存放在SD卡上。

PetaLinux的Boot参数是通过设备树中的/chosen/bootargs条目进行配置的。默认情况下,最后镜像使用的设备树中该条目会是这样的(每个字段的先后顺序不重要):

cat system-user.dtsi
bootargs = "root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1 uio_pdrv_genirq.of_id=\"generic-uio\" clk_ignore_unused";

但我们希望其中的字段root=/dev/mmcblk0p2变成root=/dev/mmcblk1p2。直觉上,首先想到的是很上文一样修改system-user.dtsi文件,从而影响最终生成的设备树。实验会告诉你完全不起作用,最后输出也就是实际使用的设备树里还是上面这行默认值。这里大家就会遇到PYNQ这个编译流程设计的很糟糕的一点:system-user.dtsi这个文件中的只有一部分会起作用,至于想弄清哪部分,要么做实验,要么看懂编译源代码。比如上面对&sdhci1节点的修改就能生效,对/chosen/bootargs对修改就不起作用。

生成设备树是制作BSP文件的中一部分,接下来我们来弄清楚PYNQ是如何生成最终的BSP文件的。我们先考虑用户没有提供预编译的BSP文件的情形,此时PYNQ内部会依次做这些事:

  1. 建立一个空的PetaLinux项目
  2. 拷贝用户的petalinux_bsp/meta-user到该项目下;
  3. 读入硬件配置即petalinux_bsp/hardware_project中的XSA文件,生成Config文件;
  4. 构建并打包成BSP文件;
  5. 利用上一步获得的BSP文件建立一个新的PetaLinux项目;
  6. 直接在脚本中修改Config文件,加入一些配置;
  7. 重新运行petalinux-config生成新的Config文件;
  8. 开始各种build,最终生成我们需要的BOOT.bin。

其中步骤1、2、3、4在sdbuild/scripts/create_bsp.sh脚本中进行,步骤5、6、7、8在sdbuild/Makefile中进行。如果用户指定了预编译的BSP文件,就把上文中的第1步换成“利用用户提供的BSP文件建立一个新的PetaLinux项目”。这里最令人困惑的地方是,为什么要进行两次“create-config-build”的流程,至少我没有看出它这么做的必要性。这样一通操作之后,用户在petalinux_bsp/meta-user的子目录下的system-user.dtsi文件中修改的一些设备树节点(对应上文步骤2),会在步骤6中被新引入的一些设备树文件冲刷掉。步骤6通过CONFIG_USER_LAYER_0这一设置混入了一些新的设备树文件,这些额外的设备树文件位于sdbuild/boot/meta-pynq/recipes-bsp/device-tree。就Boot参数而言,这里边的pynq_bootargs.dtsi文件提供了前述的默认/chosen/bootargs。因此无论我们在system-user.dtsi文件中如何修改/chosen/bootargs,最终都会被覆盖掉。

因此,我们的解决方案很简单,修改下pynq_bootargs.dtsi文件,将其中的root=/dev/mmcblk0p2变成root=/dev/mmcblk1p2。除了修改pynq_bootargs.dtsi,我们还需要修改sdbuild/Makefile,将下面这行代码中的mmcblk0p2变成mmcblk1p2

echo 'CONFIG_SUBSYSTEM_SDROOT_DEV="/dev/mmcblk0p2"' >> $$(PL_CONFIG_$1)
3、网络不工作

黑金使用的是ksz9031 phy芯片,这里提供两种设备树,放在system-user.dtsi内,供参考

第一种是在U-boot下网络可以正常工作,但是在Linux下工作异常

&gem3 {
	status = "okay";
	local-mac-address = [00 0a 35 00 02 90];
	phy-mode = "rgmii-id";
	phy-handle = <&phy0>;
	phy0: phy@1 {
		reg = <1>;
		compatible = "micrel,ksz9031";
		device_type = "ethernet-phy";
	};
};

第二种是在Linux下网络可以正常工作,但是在U-boot下工作异常

&gem3 {
	status = "okay";
	phy-mode = "rgmii-id";
	phy-handle = <&phy0>;
	local-mac-address = [00 0a 35 00 22 01];
	mdio: mdio {
		#address-cells = <1>;
		#size-cells = <0>;
		phy0: ethernet-phy@1 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <1>;
			reset-names = "phy-ksz9031";
		};
	};
};
4、PYNQ系统启动时卡mmcblk0p1

在PYNQ系统启动时,会按照/etc/fstab文件挂载各个分区,我们的SD卡为mmcblk1,而PYNQ写死的mmcblk0,导致无限尝试挂载,系统进入emergency模式,最终卡死,烧写好后将SD卡挂载进虚拟机中修改即可

/dev/mmcblk1p1 /boot vfat defaults 0 2
5、SD卡扩容失败

在PYNQ系统第一次启动时,systemd会运行扩容脚本,但是不幸的是扩容脚本写死的扩容目标分区为mmcblk0p2,导致扩容失败,修改/usr/local/bin/resizefs.sh文件即可

将TGTDEV修改为/dev/mmcblk1

将TGTPART修改为/dev/mmcblk1p2

若是已经启动过系统,则将/etc/environment中的RESIZED=1字段删除,重启即可

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值