本篇是综合工程,将较为详细的讲解如何利用vivado搭建一个AXI-DMA环通测试环境,并使用petalinux进行linux系统的部署。以QSPI的启动方式唤起emmc fat分区中的linux内核系统,并挂载emmc ext4分区中的根文件系统。同时,使用xilinx-axidma库进行AXI-DMA的环通测试
目录
0 - 准备工作
- ZYNQ7000开发板,4G eMMC挂载在SD1,SD卡槽挂载在SD0
- 已预先在eMMC中分两区,fat区用于存放image.ub与设备树文件dtb,ext分区存放着已预先搭建好的根文件系统
关于如何使用WORK-Linux(一个能运行的存储在sd卡中的linux系统)来进行eMMC分区:linux指令fdisk
关于如何搭建根文件系统:i.MX6UL #0 - ubuntu根文件系统的修改与配置(从零开始的掉头发生活)
- 根文件系统中已存放编译好的xilinx_axidma库
xilinx_axidma github:https://github.com/bperez77/xilinx_axidma
如何编译xilinx_axidma库:ZYNQ7000 #3 - Linux环境下在用户空间使用AXI-DMA进行传输
1 - VIVADO工程
vivado工程较为简单,如图所示,在基本的ps系统基础上(ZYNQ7000 #5 - 从vivado工程开始,从emmc启动Linux),添加了一个AXI Direct Memory Access IP核以及一个Concat集线器。红色是数据流环通回路,蓝色是中断信号从PL到PS的通路。在使用xilinx_axidma库时,AXI-DMA IP核的中断信号是必须连接到PS核的。
生成比特流文件,导出hdf时需要勾选包括比特流文件。这样我们就得到petalinux所需的hdf文件了
bitstream是vivado中生成的,导出为hdf文件时需要include bitstream。
hdf实际只是个压缩文件,其中包括硬件信息、bitstream等等,petalinux需要解包hdf然后将其中的bitstream用于后面进行petalinux-package
2 - petalinux工程
2.1 - petalinux工程建立
将hdf文件拷贝到已安装好petalinux的虚拟机中
运行下面的语句,加载petalinux环境
$ . /opt/pkg/petalinux/settings.sh
读取hdf文件
$ petalinux-config --get-hw-description=你的hdf文件所在文件夹路径
之后会自动打开petalinux工程配置的menuconfig
2.2 - 工程配置
修改Linux Components Selection,选择使用外部的linux内核(ZYNQ7000 #0 - petalinux的使用与工程建立(都9102年了,就用用便利的工具吧))
这里我们需要从eMMC启动Linux Kernel。所以改变主SD为挂载了eMMC的SD1,让boot image从primary flash读取,设置linux kernel存储位置为primary sd(ZYNQ7000 #5 - 从vivado工程开始,从emmc启动Linux)
修改使用eMMC中的根文件系统,eMMC已经分区,但是其挂载在的是SD1上,所以eMMC上的ext分区会被识别为mmcblk1p2。这里不需要使用tftboot,所以也取消
2.3 - UBOOT的BUG修复
整个下来唯一要操心的就只有uboot
修改uboot的project-spec\meta-user内文件,避免从sd载入dtb的错误(ZYNQ7000 #3 - Linux环境下在用户空间使用AXI-DMA进行传输)和跳过空SD0的错误(ZYNQ7000 #5 - 从vivado工程开始,从emmc启动Linux)
在 project-spec/meta-user/recipes-bsp/u-boot/files/plantform-top.h 文件末尾加入下面的代码。注意CONFIG_BOOTCOMMAND后接语句使用一个TAB制表符
#ifdef CONFIG_BOOTCOMMAND
#undef CONFIG_BOOTCOMMAND
#define CONFIG_BOOTCOMMAND "mmc dev ${sdbootdev}; run uenvboot; run cp_kernel2ram && run cp_dtb2ram && bootm ${netstart} - ${dtbnetstart}"
#endif
2.4 - 设备树修改
为了使用xilinx_axidma,我们需要修改dma通道的id,并在设备树中添加axidma_chrdev子节点
将 project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi 文件添加下面的代码
&amba_pl{
axidma_chrdev: axidma_chrdev@0 {
compatible = "xlnx,axidma-chrdev";
dmas = <&axi_dma_0 0 &axi_dma_0 1>;
dma-names = "tx_channel", "rx_channel";
};
};
&axi_dma_0{
dma-channel@40400000 {
xlnx,device-id = <0x0>;
};
dma-channel@40400030 {
xlnx,device-id = <0x1>;
};
};
这样我们就在amba_pl总线下挂载好了axidma_chrdev子节点,并且将axi_dma_0总线下的两个dma通道(一发一收)的id分别设置为了0和1
2.5 - linux内核配置
修改内核CMA大小
$ petalinux-config -c kernel
Device Drivers -> Generic Driver Options -> Default contiguous memory area size 的 Size in Mega Bytes修改为25
2.6 - 编译生成
$ petalinux-build -c kernel
$ petalinux-build -c fsbl
$ petalinux-build -c u-boot
$ petalinux-package --boot --fsbl --fpga --u-boot --force
这里不用单独来 build device-tree 其会在编译 kernel 时一同生成
使用dtc反编译dtb,查看dts内容是否被修改为期望的样子
dtc -I dtb -O dts -o system.dts system.dtb
将BOOT.BIN image.ub system.dtb复制到物理机备用
3 - 部署运行测试
3.1 - 覆写新的BOOT.BIN与image.ub
启动预制的WORK-Linux,通过ssh上传文件
擦除QSPI FLASH上的mtd0,写入新的BOOT.BIN
$ sudo su
$ flash_eraseall /dev/mtd0
$ dd if=BOOT.BIN of=/dev/mtdblock0
挂载eMMC上的FAT分区
清除FAT分区上原有的image.ub 和 system.dtb 将新的写入
将磁盘缓存写入,重启
3.2 - 运行测试
重启后进入之前已经编译好放置在emmc根文件系统上的xilinx_axidma-master\outputs文件夹
insmod 挂载axidma模块,dmesg查看报告是否正确,这里的确检测到了一个发送一个接受通道
运行测速例程,查看是否正常
也可以运行自己编写的测试例程(ZYNQ7000 #4 - Linux环境下使用AXI-DMA读取PL外接ADC)