AXI-DMA的linux驅動
一、搭建硬體環境
vivado版本2017.4,晶片為7010,不過不管什麼版本和晶片大緻步驟是一樣的
本文工程檔案:https://gitee.com/long_fly/AXIDMA_linux
硬體平台PL的搭建同ZYNQ基礎系列(六) DMA基本用法,在這個工程的基礎上添加SD卡(根據自己的開發闆硬體選擇相應的引腳)
然後直接生成bit檔案,然後記得要導出硬體(包含bit檔案)進SDK
二、生成裝置樹
1.解壓裝置樹工具檔案夾到一個地方
在https://github.com/Xilinx/device-tree-xlnx下載下傳
2.菜單欄 –> Xilinx –> Repositories
添加剛剛解壓的位置
3.菜單欄 –> File –> New –> Board Support Package
建立BSP,可以發現多了一欄device_tree,直接點确定到下一步
4.設定環境變量
内容為:
console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext4 earlyprintk rootwait
5.最後可以在工程檔案夾中找到生成的裝置樹檔案
待用
三、生成FSBL引導檔案
1.在SDK中建立一個APP,選擇FSBL模闆工程,然後完成建立
2.使能調試資訊列印
添加
#define FSBL_DEBUG_INFO
後,儲存檔案,會生成
FSBL.elf
檔案,檔案待用
四、編譯u-boot
0.具體的相關環境(不裝會報錯)和SDK環境安裝(不裝沒法編譯,建議去官網下載下傳)
參考ZYNQ跑系統 系列(一) 傳統方式移植linux,不再贅述;u-boot和kernel直接在https://github.com/Xilinx下載下傳;還有注意以下路徑是我自己的,要根據實際修改相應路徑
1.linux超級使用者模式,定位settings64.sh檔案(在SDK安裝檔案夾裡)
source /opt/Xilinx/SDK/2017.1/settings64.sh
2.進入u-boot目錄(自己解壓的路徑)
cd /home/hlf/mnt/u-boot-xlnx-master
3.打開GUI配置u-boot
make menuconfig
,load預配置的檔案,絕對路徑為
/home/hlf/mnt/u-boot-xlnx-master/configs/zynq_ax7010_defconfig
,觀察了一下沒什麼需要修改的,直接儲存并退出
4.讀配置檔案(zynq_ax7010_defconfig)
make CROSS_COMPILE=arm-xilinx-linux-gnueabi- zynq_ax7010_defconfig
5.編譯
make CROSS_COMPILE=arm-xilinx-linux-gnueabi-
6.檢視 u-boot 檔案的不同段的記憶體配置設定情況 (可以不看)
arm-xilinx-linux-gnueabi-objdump -h u-boot
7.修改字尾為u-boot.elf,待用
五、編譯kernel
1.進入kernel目錄(自己解壓的路徑)并和之前一樣定位檔案
cd /home/hlf/mnt/linux-xlnx-master
source /opt/Xilinx/SDK/2017.1/settings64.sh
2.打開GUI配置kernel
make ARCH=arm menuconfig
,load預配置的檔案,絕對路徑為
/home/hlf/mnt/linux-xlnx-master/arch/arm/configs/xilinx_zynq_defconfig
,這裡不通過GUI方式更改配置,關閉
3.開啟DMA的相關功能
也可以不通過GUI的方式配置kernel,這裡我們直接指令行(要在超級使用者模式下,不然沒有權限修改):
gedit /home/hlf/mnt/linux-xlnx-master/arch/arm/configs/xilinx_zynq_defconfig
打開檔案,確定以下選項開啟(=y)
CONFIG_CMA=y
CONFIG_DMA_CMA=y
CONFIG_XILINX_DMA_ENGINES=y
CONFIG_PL330_DMA=y
CONFIG_XILINX_DMA=y
CONFIG_XILINX_AXIDMA=y
CONFIG_XILINX_AXIVDMA=y
CONFIG_DMA_SHARED_BUFFER=y
4.讀配置
make ARCH=arm xilinx_zynq_defconfig
5.編譯核心
make ARCH=arm CROSS_COMPILE=arm-xilinx-linux-gnueabi- uImage LOADADDR=0x00008000
6.編譯完成後,指令行會提示生成的uImage的位置
uImage拷貝出來待用
7.生成devicetree.dtb
将裝置樹檔案夾拷貝到虛拟機的相應路徑下
在
pl.dtsi
中添加:
axidma_chrdev: axidma_chrdev@ {
compatible = "xlnx,axidma-chrdev";
dmas = <&axi_dma_0 &axi_dma_0 >;
dma-names = "tx_channel", "rx_channel";
};
儲存後,生成devicetree.dtb:
./scripts/dtc/dtc -I dts -O dtb -o /home/hlf/mnt/device_tree_bsp_0/devicetree.dtb /home/hlf/mnt/device_tree_bsp_0/system-top.dts
六、準備運作linux
1.生成BOOT.bin
之前産生了
FSBL.elf
、
u-boot.elf
和
bit檔案
,直接通過SDK生成
BOOT.bin
2.拷貝檔案至SD卡
将之前産生的
BOOT.bin
、
devicetree.dtb
和
uImage
拷貝到SD卡
3.插上序列槽開機運作
確定可以運作系統
七、編譯例程
0.下載下傳例程
例程下載下傳位址:https://github.com/bperez77/xilinx_axidma或者https://gitee.com/long_fly/AXIDMA_linux
1.拷貝例程檔案夾到kernel檔案夾裡
我将檔案夾命名為了
extra
,直接将例程檔案夾的内容放到裡面,如果沒有權限的話,直接指令行
chmod 777 檔案夾名
擷取相應權限就可以了
2.cd到extra檔案夾裡
3.編譯
使用交叉編譯鍊,定位到kernel(已經編譯好的)的路徑,編譯driver:
make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm KBUILD_DIR=/home/hlf/mnt/linux-xlnx-master/ driver
使用交叉編譯鍊,編譯examples:
make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm examples
編譯完成後,生成檔案将出現在
outputs
檔案夾裡
4.将這些檔案拷貝到SD卡中,開機
5.挂載SD卡
cd ..
到達系統目錄
mount /dev/mmcblk0p1 /mnt
挂載SD卡
cd /mnt
進入SD目錄
insmod axidma.ko
載入剛剛生成的子產品
列印資訊提示通道的ID沖突
6.修改裝置樹中通道的ID号
然後按照之前的步驟重新生成
devicetree.dtb
,将新裝置樹檔案拷貝到SD卡中,然後開機,挂載SD卡,加載子產品
這次沒有列印資訊提示ID沖突
7.檢視是否成功
cd /dev
到達dev目錄
ls
檢視内容
會發現多了一個axidma,然後運作
dmesg
,可以看到如下資訊:
8.運作例程裡的APP1
發現CMA記憶體不夠,導緻接收緩存空間申請不了這麼大,在裝置樹檔案夾中修改
.dts
字尾的檔案,添加cma空間的申請
然後重新生成
devicetree.dtb
檔案,拷貝到SD卡中,開機,挂載SD卡,加載子產品,運作APP
可以測試收發通道的資料速率
9.運作例程裡的APP2
在SD卡中建立兩個文本,在其中一個文本檔案中寫入内容,另一個為空
運作應用程式,将檔案1的内容通過DMA環路寫入檔案2,因為檔案太小了,是以顯示的是0.00Mb
運作結束後打開檔案2,會發現和檔案1裡的内容完全一緻
八、代碼分析與修改及應用到VDMA
……