linux系统移植及AXI DMA配置
linux系统移植及AXI DMA配置
petalinux2021 + vivado2021
dma驱动代码:
https://github.com/bperez77/xilinx_axidma/tree/master
1、配置环境
安装petalinux的时候已经配置好了环境,因此终端直接输入sptl就可以开启相关环境使用
2、创建工程
mkdir petalinux
cd petalinux
petalinux-create -t project --template zynq -n ALINX-ZYNQ
3、导入硬件描述文件
mkdir hdf
首先,创建一个带有axi dma回环的vivado工程,其中block design的搭建如下:(下图dma没有开启SG模式)
尤其注意axi dma的设置中,width of buffer length register要设置为24及以上,因为之后的一个测试例程需要往buffer里面填充约8MB的数据,因此需要开辟收发各8MB的空间
生成bit stream之后,导出硬件描述文件,vivado2021的硬件描述文件为.xsa文件,将其拷贝到hdf文件夹下,然后
cd ALINX-ZYNQ
petalinux-config --get-hw-description …/hdf
短暂等待后会弹出窗口,在image packaging configuration中,在Root filesystem type中选择ext4,如果保持默认会启动一个自带的linux根文件系统,然后关闭Copy final images to tftpboot,因为我用不到所以就关了,不关的话在image/linux文件夹下生成的image可能不是最新的。其它选项保持默认。
4、设备树配置
petalinux-config -c device-dree
该命令可以在/ALINX-ZYNQ/components/plnx_workspace/device-tree/device-tree/下生成设备树,我们主要关注pl.dtsi
可以看到两个dma-channel的xlnx,device-id都是0x0,因此我们需要修改设备树,但不是在这里修改
petalinux工程下提供了一个可以修改设备树的文件/ALINX-ZYNQ/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi,增加内容如下:
/include/ "system-conf.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>;
};
};
一定要注意&axi_dma_0和后面的{之间是有一个空格的,网上有一个教程漏了这个空格,不会报语法错误,但是修改不生效。还有教程说需要把这个文件修改后拷贝到/ALINX-ZYNQ/components/plnx_workspace/device-tree/device-tree/下才能生效,实测是不需要的。
petalinux-build -c device-tree -x cleansstate 清理设备树编译状态
petalinux-build -c device-dree 编译设备树
5、编译内核
petalinux-config -c kernel
等待一段时间后会弹出配置窗口,如果是第一次配置会需要等待相当长的时间
在Library routines下修改Size in Mega Bytes,改为25
在General architecture-dependent options下关闭stack Protector buffer overflow detection,这个如果不关闭下一步编译make driver的时候会报gcc-plugin的错误,这个错误好像不少人遇到过,比如如下这个链接,但是提问者已经意识到是stack相关的错误,但是并未找到解决方案,我尝试着关闭这个选项就不会报错了。
之后编译内核
petalinux-build -c kernel
6、编译驱动
下载驱动源码:
https://github.com/bperez77/xilinx_axidma/tree/master
之后需要对驱动源码做修改,修改方式如下:
https://github.com/bperez77/xilinx_axidma/issues/127
具体是:
axi_dma.c (add in line 18):
增加 #include <linux/of_address.h>
axidma_chrdev.c (change in line 277):
将 of_dma_configure(dev->device, NULL);
替换成of_dma_configure(dev->device, NULL, true);
axidma_dma.c (chang in line 146):
将 struct siginfo sig_info;
替换成struct kernel_siginfo sig_info;
axidma_chrdev.c (change in line 329):
将 if (!readonly && !access_ok(VERIFY_WRITE, arg, size)) {
替换成if (!readonly && !access_ok(arg, size)) {
axidma_chrdev.c (change in line 333):
将 } else if (!access_ok(VERIFY_READ, arg, size)) {
替换成} else if (!access_ok(arg, size)) {
再将config_template.mk拷贝一份重命名为config.mk,将其中的内容进行修改:
第21行改为 CROSS_COMPILE = arm-linux-gnueabihf-
第25行改为 ARCH = arm
第35行改为 KBUILD_DIR = /home/he/LabPan/SLAM/petalinux/ALINX-ZYNQ/build/tmp/work/zynq_generic-xilinx-linux-gnueabi/linux-xlnx/5.10+gitAUTOINC+568989d441-r0/linux-zynq_generic-standard-build
第41行改为 OUTPUT_DIR = outputs
这个KBUILD_DIR是其中最麻烦的,它是存放linux内核编译后的结果的文件夹,是petalinux-build -c kernel之后才有的。
之后
make driver
make examples
生成outputs文件夹,并在文件夹下找到axidma.ko文件
7、最终编译
回到ALINX-ZYNQ/目录下
petalinux-build
petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --fpga --u-boot --force
8、替换根文件系统
我没有用petalinux生成的根文件系统,而是替换成了ubuntu
https://blog.csdn.net/weixin_40407893/article/details/118019142
9、上板查看结果
将images/linux下的boot.scr、BOOT.BIN和image.ub文件拷贝到SD卡的FAT分区,将axidma驱动的outputs文件夹拷贝到ext4的根文件系统的home目录下
上板后,首先挂载驱动
insmod axidma.ko
然后就可以跑例程了
./axidma_benchmark