本文后续更新和资源在个人主页,欢迎点此查看

前言

在Zynq中移植Linux一直是对于我们这种初学者来说的老大难问题,这一问题在官方推出Petalinux后有所缓解。但Petalinux OS的操作简便性不如已经十分成熟的桌面系统Ubuntu,目前网上的教程大多侧重于利用Petalinux生成完设备树和内核后替换Ubuntu的rootfs。事实上,在Vitis AI横空出世后,Xilinx给出了一个已经为Zynq MPSoc移植好的Ubuntu,并起名为Xilinx Certified Ubuntu。该版本是一个Golden镜像,可以将大多数硬件接口驱动起来。但如果想在PL端作出修改并在Linux中驱动起来,则需要自己重构设备树和Bitstream。利用Xilinx Certified Ubuntu的好处还有:

  • 提供xlnx-config、fpga-manager-xlnx、bootgen-xlnx等多种工具的snap镜像,实现在linux端管理PL资源。
  • 利用xlnx-config,实现各种配置好的平台资源(PAC)的切换,并自动生成Boot镜像,重启后直接生效。
    对于因编写出错无法引导的镜像,将再重启后尝试引导失败后回滚为Golden镜像。
  • More

本文将一步步从裸板上实现Xilinx Certified Ubuntu安装、自定义硬件平台设计、构建自定义平台资产(PAC)、硬件资产在Linux上进行切换等步骤。作为学习记录,也希望对大家有帮助。

Step1:安装并启动Xilinx Certified Ubuntu

访问Ubuntu官方网站下载固件:https://ubuntu.com/download/amd-xilinx

截止发文时,最新的固件为20.04LTS。下文将以20.04LTS为例。

将SD卡插入读卡器,将下载下来的.xz压缩包解压成img,利用镜像烧写工具将下载下来的镜像烧写到SD卡上。(推荐balenaEtcher,各操作系统通用)。

插入电源、USB-UART连接线、SD卡,有显示器和键盘啥的也可以插上。调整ZCU102上的SW6开关到下图所示(来自UG1182官方文档,尤其注意官方文档的Pins序号是[4:1]不是[1:4]…当时坑死我了调了半天)


官方手册的指示

实际位置

将UART连接到电脑(前提是装好CP210X串口芯片的驱动)后可以看到端口多了4个,打开Interface 0(波特率115200,8位数据,1位停止,无校验位),打开电源,看看有没有串口信息打印出来。


一切正常的话就能看到Ubuntu系统已经引导成功了。用户名密码都是ubuntu。

下面让我们仔细分析一下启动流程,来方便我们日后用自己的硬件平台替换。


启动过程
SD卡内的文件如下:

  • boot.bin (板子识别和镜像选择ImgSel)
  • boot 10(2,4,6)1.bin (ZCU102/104/106专用镜像)
  • boot.scr.uimg (Uboot)
  • image.fit
  • meta-data,network-config,user-data (linux需要的数据)

Xilinx在启动时,BootROM会先检测设备模式引脚状态,SD卡启动时会搜SD卡第一个分区有无boot.bin,如果没有则在后面加数字,搜索boot1.bin,boot2.bin…一直到boot8191.bin,这种模式被称为MultiBoot。在Certified Ubuntu中,boot.bin是一个最小的应用程序(ImgSel),用于确定是在哪个板子上运行,随后把boot过程移交给更强大的FSBL执行。在本例中,ImgSel检测到了102板子,将1020写入MultiBoot寄存器,BootROM从boot1020.bin开始找,最终找到boot1021.bin(转为ZCU102设计的Golden镜像)启动。前文所说的利用xlnx-config进行镜像管理,本质上就是打包boot1020.bin并写入SD卡,在boot1020.bin失效后自动回滚会Golden镜像boot1021.bin。

具体启动参考右图(源于参考[2])

Step2 用Vivado创建自己的硬件平台

打开Vivado,选择ZCU102板,Create Block Design.

添加一个Zynq核心,先Run Block Automation,弹出窗口内选择Apply Board Preset,这样后面可以少配很多东西。
添加一个AXI GPIO用于测试读写开发板引脚,一个AXI BRAM Controller用于BRAM测试。
Generate Block Design -> 右键单击bd -> Create HDL Wrapper
写约束
Generate Bitstream
File -> Export Hardware 导出xsa
打开Vitis,新建一个Platform Project,选择刚刚导出的xsa。

构建该Platform Project


构建
构建成功后,取出下列两个文件

/zynqmp_fsbl/fsbl_a53.elf
/zynqmp_pmufw/pmufw.elf

接着,进行设备树导出。

如果你第一次进行这个操作,需要在任意位置拉取Xilinx的Device Tree Generator,不然会报错。

git clone https://github.com/Xilinx/device-tree-xlnx
cd device-tree-xlnx
git checkout <你的套件版本,如xlnx_rel_v2021.2>

在Vitis中,选择Xilinx->Software Repositories,添加刚刚拉取的仓库本地文件夹地址



接着,选择Xilinx->Generate Device Tree,选择xsa,并配置导出文件夹。


生成的文件如图,因为XSA文件仅包含用户定义的IP和Zynq,因此要激活Ethernet网络,需要自己编写设备树,修改其中的system-top.dts来添加Ethernet的PHY(踩坑*n)同时还需要加入model和compatible字段来让Uboot/Ubuntu正确识别硬件开发板信息、加载驱动程序(再次踩坑)。(参考:https://github.com/Xilinx/u-boot-xlnx/blob/3113b53d8cb1913ef8162cadf45f44ebf2ed9eea/arch/arm/dts/zynqmp-zcu102-revA.dts)

/dts-v1/;
#include "zynqmp.dtsi"
#include "zynqmp-clk-ccf.dtsi"
#include "pl.dtsi"
#include "pcw.dtsi"/ {model = "ZynqMP ZCU102 Rev1.1";compatible = "xlnx,zynqmp-zcu102-rev1.1", "xlnx,zynqmp-zcu102", "xlnx,zynqmp";chosen {bootargs = "earlycon";stdout-path = "serial0:115200n8";};aliases {ethernet0 = &gem3;i2c0 = &i2c0;i2c1 = &i2c1;serial0 = &uart0;serial1 = &uart1;spi0 = &qspi;};memory {device_type = "memory";reg = <0x0 0x0 0x0 0x7ff00000>, <0x00000008 0x00000000 0x0 0x80000000>;};
};&gem3 {status = "okay";phy-handle = <&phy0>;phy-mode = "rgmii-id";pinctrl-names = "default";phy0: ethernet-phy@c {reg = <0xc>;ti,rx-internal-delay = <0x8>;ti,tx-internal-delay = <0xa>;ti,fifo-depth = <0x1>;ti,dp83867-rxctrl-strap-quirk;/* reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; */};
};

接着,来编译设备树Blob文件(DTB),进入生成的设备树目录。该步骤需要在Linux系统下进行。

gcc -I my_dts -E -nostdinc -undef -D__DTS__ -x assembler-with-cpp -o system-top.dts.tmp system-top.dtsdtc -I dts -O dtb -o system-top.dtb system-top.dts.tmp


至此,在文件夹内出现设备树文件system-top.dtb,进行保存

接下来,编译ARM可信固件(ATF)

git clone https://github.com/Xilinx/arm-trusted-firmware.git
cd arm-trusted-firmware

这个存储库里面有个软连接到linux库,遇到报错要自己删了软连接重建一下,具体是哪个我忘记了。。处理完以后

make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1

来进行交叉编译,编译好会生成bl31.elf,保存下来。

现在我们有这些文件:

)
把Vivado生成的PL Bitstream也保存到这里,命名为system.bit。接下来,我们新建一个文件,命名为bootgen.bif,内容如下:

the_ROM_image:
{[bootloader, destination_cpu=a53-0] fsbl_a53.elf[pmufw_image] pmufw.elf[destination_device=pl] system.bit[destination_cpu=a53-0, exception_level=el-3, trustzone] bl31.elf[destination_cpu=a53-0, load=0x00100000] system-top.dtb[destination_cpu=a53-0, exception_level=el-2] /usr/lib/u-boot/xilinx_zynqmp_virt/u-boot.elf
}

这些文件的意义,Xilinx Wiki有相应介绍。

bootgen.bif 用于生成boot.bin的描述文件
fsbl_a53.elf First Stage Bootloader
system.bit PL的Bitstream文件
bl31.elf ARM可信固件
system-top.dtb 设备树文件,需要与system.bit对应
uboot.elf u-boot文件,对于ZCU102,可以直接使用Certified Ubuntu系统内 /usr/lib/u-boot/xilinx_zynqmp_virt/u-boot.elf
dpu.xclbin (可选) system.bit的DPU配置
pmufw.elf Platform Management Unit (PMU)固件

前面讲了这么多,之后我们替换新的硬件平台的时候只要考虑system.bit、system-top.dtb、dpu.xclbin就可以了,其他的build都是一劳永逸的。

或者你是在不想build,对于fsbl、bl31,都可以使用Certified Ubuntu内的golden镜像,存储路径在:

/usr/share/xlnx-firmware/zcu10[x]

接下来,我们按照xlnx-config工具的要求将上述文件按如下存放(其中,test_pac文件夹存放在/boot/firmware/xlnx-config中。因为/boot/firmware就是SD卡的挂载点,所以也可以直接在SD卡上操作)

test_pac/
└── hwconfig├── test_pac│   ├── manifest.yaml│   ├── zcu102│   │   ├── bl31.elf│   │   ├── bootgen.bif│   │   ├── fsbl_a53.elf│   │   ├── pmufw.elf│   │   ├── system.bit│   │   └── system-top.dtb

manifest.yaml内如下:

name: test_platform
desscription: Boot assets for the 2021.2 test design
revision: 1
assets:zcu102: zcu102

Step 3 激活自定义硬件平台(PAC)

首先需要安装Xilinx官方的工具xlnx-config(snap拉取的失败率挺高的。。)

sudo snap install xlnx-config --classic --channel=1.x
xlnx-config.sysinit

如果没有snap,要先安装snap,再执行上述操作

sudo snap install snap-store

安装完毕后,输入 xlnx-config -q 可以看见刚刚我们设置的自定义硬件平台


使用 sudo xlnx-config -a test_pac 激活我们刚刚设置的平台,工具会自动打包成boot.bin并放到SD卡命名为boot1020.bin。重启后生效。


重启后,可以通过xlnx-config -q查看激活的资产

参考

[1] Getting Started with Certified Ubuntu 20.04 LTS for Xilinx Devices

[2] Booting Certified Ubuntu 20.04 LTS for Xilinx Devices

[3] Build ARM Trusted Firmware (ATF)

[4] Snaps – xlnx-config Snap for Certified Ubuntu on Xilinx Devices

[5] Xilinx/embeddedsw

[6] Xilinx/linux-xlnx

[7] Device Trees

[8] Solution ZynqMP PL Programming

[9] Creating Devicetree from Devicetree Generator for Zynq Ultrascale and Zynq 7000

[10] Xilinx/u-boot-xlnx

Zynq MPSoC在自定义硬件平台中移植使用Xilinx Certified Ubuntu踩坑实录(以ZCU102为例)相关推荐

  1. JAVA发布栅格图层_基于 WebGL实现自定义栅格图层踩坑实录

    以下内容转载自totoro的文章<WebGL-Y轴翻转踩坑实录> 作者:totoro 链接:blog.totoroxiao.com/webgl-flipY- 来源:blog.totorox ...

  2. Java在MVC开发模式中使用try-catch以及throws避免踩坑

    场景 1.throws是在方法上抛出异常,throw是在语句上抛出异常. 2.try-catch是在catch里处理try捕获异常并处理. 3.一般try-catch是在上层Controller中使用 ...

  3. 复现CLOCs中spconv v1.0 (commit 8da6f96)踩坑记录

    最近看了一篇基于KITTI做2D和3D后融合的论文,CLOCs: Camera-LiDAR Object Candidates Fusion for 3D Object Detection.作者在Gi ...

  4. 在基于ZYNQ MPSOC XCZU3CG自定义单板上运行DPU例程

    在上一篇博文中FZU3构建Linux系统,描述了Edgeboard FZU3构建Linux系统的过程,本文在上篇基础上详细描述在FZU3上运行DPU例程的方法.DPU例程代码参考如下链接:DPU例程 ...

  5. otter自定义数据同步踩坑实录

    otter自定义数据同步 otter支持数据处理自定义过程. Extract模块: EventProcessor : 自定义数据处理,可以改变一条变更数据的任意内容 FileResolver : 解决 ...

  6. zookeeper一键启动关闭JAVA_HOME在PATH中找不到报错踩坑记

    最近看了尚硅谷的zookeeper教程,在集群环境搭建中, 有这么一个脚本zk.sh用来一键启动和查询 #!/bin/bash case $1 in "start"){for i ...

  7. qt中mysql怎么支持事务_Qt踩坑之mysql数据库不支持事务操作?

    文章已更新,最新地址:https://www.fearlazy.com/index.php/post/145.html 现象: 在调试数据库操作时发现还没commit数据已经插入表中,执行rollba ...

  8. 【Unity游戏开发】Android中如何集成Unity3D项目——入门级踩坑

    最近的学习之路真的是波折,先是想学Kotlin,结果赶上了算法比赛,恶补了几天算法,然后回归Kotlin,这周又需要调研一下Unity3D,需要把Unity项目嵌入到我们的Android项目中. 今天 ...

  9. 在Vue中使用vant的方法,踩坑in ./node_modules/vant/es/dialog/Dialog.js

    步骤一:使用npm安装vant npm install vant -force 因为可能会产生依赖冲突,所以一般会在后面加上 -f 强制执行 步骤二:导入vant包 在Vue项目的main.js文件中 ...

最新文章

  1. 利用标准库sprintf、sscanf函数实现字符串和数字的转换
  2. Java项目:高校学生社团活动管理系统(java+springboot+freemark+jpa+mysql)
  3. python解多项式方程_python – SymPy不能求解四阶多项式方程
  4. linux 重新加载驱动程序,在linux中模拟设备驱动程序崩溃。让python重新加载i
  5. Vue.js 状态管理
  6. 2021年计算机网络期末考试题,2021年计算机网络期末考试试题及答案-20210515145802.doc-原创力文档...
  7. linux 下 etc常用配置信息
  8. linux之Vim使用
  9. 修改mysql的用户密码
  10. Smarty模板技术学习
  11. ListView(列表)
  12. 微信小程序教程笔记6
  13. linux复习题之阶段性考试题目
  14. [Android1.6]动态添加View的问题
  15. SVN客户端安装详细教程
  16. 使用Python进行局域网传输文件两种方法
  17. TP-LINK配置无线上网短信Wifi认证方式
  18. 校园网显示dns服务器解析出错,天翼校园网dns解析出错怎么办
  19. 【算法】O(n2)时间复杂度和O(nlogn)排序算法的简要分析
  20. 如何制作朋友圈搞笑证件图片(附源码实例)

热门文章

  1. Ros机器人之(二)两个小海龟画圈圈
  2. HTML5期末学生大作业:基于HTML+CSS+JavaScript书城小说书籍网站带首页psd(6页)
  3. python安装(Ubuntu)
  4. ubuntu下chrome浏览器字体颜色修改
  5. STL:generate()和generate_n()
  6. 网工日常必备思科华为设备命令对照表,全网最完整
  7. 一个人的心,最不会说谎
  8. 低光照图像增强算法汇总
  9. 基于LED的温度检测(目标检测到--OCR)
  10. windows中安卓子系统安卓