ZYNQ 在Linux系统层上通过DMA传输数据(安装控制DMA驱动的设备驱动)
编译Linux 驱动有两种方法,一种是使用petalinux直接编译进入内核中,第二种是在外部通过arm内核编译之后,insmod加载进入内核。
我使用的是ZYNQ芯片,在芯片中跑Linux系统,我想解决的目标是通过DMA驱动从PS端传输数据到PL端。因为DMA驱动位于设备驱动的下一层,用户模式在设备驱动的上一层;而且DMA驱动对硬件的地址有要求,必须分配连续的物理内存,而在用户层只能分配非连续的内存页,所以需要一个驱动转换映射到物理地址才能给DMA驱动使用。我的工作目的就是安装上管理DMA驱动的设备驱动!
先介绍第一种:使用外部Linux内核编译驱动
先要build出一个基于arm的Linux内核,可以参考这篇博客:zynq linux驱动之传统开发
我在编译内核时候出现问题,找不到arm-linux-guneabihf-gcc模块。arm-linux-guneabihf-gcc是基于arm架构的gcc编译器,没有的话直接安装就行,因为我是Ubuntu系统所以使用命令:apt-get install gcc-arm-linux-gnueabihf 进行安装。
接下来使用arm的内核编译我们的驱动文件,我使用的xilinx官方提供的dma-proxy驱动文件,它可以控制DMA驱动的使用,并且提供了用户态的test example给我们熟悉怎么使用DMA driver。
通过Makefile编译dma proxy的内核.C源文件,得到dma-proxy.ko文件,去加载到Linux系统中。
这是dma proxy的Makefile,KERN_DIR设置为已经编译成功的arm Linux kernel location 。
因为dma proxy为platform_driver,所以需要注册设备树,但是现在我还没有解决这个问题,等我解决这个问题了,我就更新这里!
第二种方法为:通过petalinux把驱动直接编译进入Linux中
使用 GitHub 中作者提供的 AXI DMA的驱动模块,来传输数据。
先用petalinux定制Linux系统,导出 design_1_wrapper.hdf 文件,放到 linux_base 文件夹中,source petalinux 和 vivado 环境。
petalinux-create --type project --template zynq --name ax_peta
cd ax_peta
petalinux-config --get-hw-description ../linux_base.sdk
petalinux-config -c kernel
(配置Linux内核一定要把xilinx DMA engine都选中,可以参考GitHub上的Linux Kernel配置)
petalinux-build
下载GitHub的axi dma资源,解压,然后把所有的文件移动到petalinux的工程下,输入命令Creating and Adding Custom Modules(ug1144-petalinux-tools-reference-guide )
petalinux-create -t modules -n xilinx-axidma --enable
然后把资源文件拷贝到module的文件夹下,并且删除xilinx-axidma.c文件。以下是shell命令作为参考:
path/to/PetaLinux/project>/project-spec/meta-user/recipes-modules/xilinx-axidma/files
cp -a driver/*.c driver/*.h include/axidma_ioctl.h <path/to/PetaLinux/project>/project-spec/meta-user/recipes-modules/xilinx-axidma/files
拷贝文件到module目录
rm <path/to/PetaLinux/project>/project-spec/meta-user/recipes-modules/xilinx-axidma/files/xilinx-axidma.c
删除xilinx-axidma.c文件
<path/to/PetaLinux/project>/project-spec/meta-user/recipes-modules/xilinx-axidma/files/Makefile
修改Makefile文件,删除Makefile第一行,取代为下面三行代码:
DRIVER_NAME = xilinx-axidma
$(DRIVER_NAME)-objs = axi_dma.o axidma_chrdev.o axidma_dma.o axidma_of.o
obj-m := $(DRIVER_NAME).o
<path/to/PetaLinux/project>/project-spec/meta-user/recipes-modules/xilinx-axidma/xilinx-axidma.bb
修改xilinx-axidma.bb文件:
SRC_URI = "file://Makefile \
file://axi_dma.c \
file://axidma_chrdev.c \
file://axidma_dma.c \
file://axidma_of.c \
file://axidma.h \
file://axidma_ioctl.h \
file://COPYING \
"
1.根据之前petalinux-build生成的pl.dtsi
,将其中的内容全部复制到system-conf.dtsi
,这两个文件的地址均在<path/to/PetaLinux/project>/components/plnx_workspace/device-tree/device-tree
,这部分复制进system-user.dtsi也可以,<path/to/PetaLinux/project>/components/plnx_workspace/device-tree/device-tree
这个目录下的文件一般是自动生成的。
2.同时删除system-top.dtsi
最后一行#include system-user.dtsi
3.
修改system-user.dtsi(位置/project-spec/meta-user/recipes-bsp/device-tree/files/”
),加入以下内容:
axidma_chrdev: aaa@qq.com {
compatible = "xlnx,axidma-chrdev";
dmas = <&axi_dma_0 0 &axi_dma_0 1>;
dma-names = "tx_channel", "rx_channel";
petalinux-build
petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf
--fpga ./images/linux/design_1_wrapper.bit --u-boot --force
生成的文件BOOT.bin、image.ub位于<path/to/PetaLinux/project>/images/linux/下
(我当时petalinux-build的时候没有成功,发现我修改plnx-workspace目录下的设备树文件被还原了,也不知道什么情况,再修改一次就好了)
我当把BOOT.bin、image.ub文件放入SD卡,启动FPGA的时候出现 Bad FIT kernel image format! 问题。
原因是因为FIT文件损坏。
所以在把SD卡进行格式化的时候要格式化为FAT32格式,而且一定要安全弹出,不要直接热插拔,文件很容损坏!
接下来对DMA驱动进行读写测试。。。未完待续!