ZYNQ7000搭建嵌入式Linux操作系统-增加PL端以太网
一、VIVADO工程建立
这部分请参考我上篇讲述搭建操作系统的文章
二、VIVADO工程设置
zynq核的搭建也请参照上篇文章,不过需要增加一些内容;
双击zynq核,进入zynq的配置;
选择PS-PL Configuration,选中General—>Enable Clock Resets—>FCLK_RESET0_N
选中AXI Non Secure Enablement—> GP Master AXI Interface —> M AXI GP0 Interface
选中HP Slave AXI Interface —> S AXI HP0 interface
选择Clock Configuration,选中PL Fabric Clocks —> FCLK_CLK0,并修改Requested Frequency(MHz)
选择Interrupts,打开Fabric Interrupts —> PL-PS Interrupts Ports —> IRQ_F2P[15:0]
单击ok,完成配置;
单击上方的Run Block Automation,弹出的窗口中单击ok;
单击Diagram窗口的+号,输入1g,双击选择添加AXI 1G/2.5G Ethernet Subsystem;
添加了一个新的IP核,这个IP核是用来扩展开发板以太网的,需要申请Tri Mode Ethernet MAC这个ip核的license,申请方法可以参考这个链接
双击此IP核,进入AXI 1G/2.5G Ethernet Subsystem的配置,并按照下图配置;(这个根据自己的开发板配的以太网PHY模块进行配置,我的是RGMII)
其他页面不需要修改,直接点ok;
配置完后,点击上方的Run Block Automation,弹出的页面中使用默认配置,点击ok;
点击上方的Run Connection Automation,弹出窗口;
全部勾中,并使用默认配置,单击ok;
再单击上方的Run Connection Automation,弹出窗口;
依然全部勾中,使用默认配置,点击ok;
点击Diagram窗口上部的加号,输入xlc,添加concat这个ip核;
双击配置这个ip核;
把Number of Ports改为4,单击ok;
然后按照黄线这样进行连线;
connect_bd_net [get_bd_pins axi_ethernet_0/mac_irq] [get_bd_pins xlconcat_0/In0]
connect_bd_net [get_bd_pins axi_ethernet_0/interrupt] [get_bd_pins xlconcat_0/In1]
connect_bd_net [get_bd_pins axi_ethernet_0_dma/mm2s_introut] [get_bd_pins xlconcat_0/In2]
connect_bd_net [get_bd_pins axi_ethernet_0_dma/s2mm_introut] [get_bd_pins xlconcat_0/In3]
connect_bd_net [get_bd_pins processing_system7_0/IRQ_F2P] [get_bd_pins xlconcat_0/dout]
Ctrl+s保存,右键点击Sources 里面的design_1(design_1.bd),在弹出的窗口中点击Create HDL Wrapper…;
在弹出的窗口选择第二项,并点击ok;
Sources窗口里就会生成新的.v顶层文件;
点击左边的Run Synthesis,弹出的窗口都选择默认的选项即可。等待一段时间;
完成综合后,选择第二项,点击ok;
出现新的界面;
点击上方的Window—>I/O Ports;
在下方会出现新窗口,在这个窗口中对管脚进行约束;
在窗口中完成管脚约束后,按下Ctrl+s保存到约束文件中;
约束过的管脚会在Fixed一栏打上勾;
点击左边的Generate Bitstream,等待生成bit流文件成功即可;
三、虚拟机下生成内核和uboot.elf
上一篇中生成的uboot.elf不需要修改,直接可以用;
如果没有生成过uboot.elf,请参考上一篇生成uboot的内容;
本部分主要叙述内核配置和生成;
上一篇文章中讲述了如何使用xilinx_zynq_defconfig生成内核配置,这次咱们要在之前的内核基础上进行修改;
首先进入虚拟机,在图形化界面下进入放置内核源码的目录,我的放在了/home/<用户名>/Download/下;
进入文件夹,右键单击文件夹内空白处,点击Open in Terminal;
输入命令:
sudo su
<输入密码,不可见>
apt-get install libncurses5-dev -y
source /tools/Xilinx/SDK/2019.1/settings64.sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig //这里是拷贝zynq的默认内核配置
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf menuconfig
进入内核配置界面;
使用方法在上方有说明。
现在我要搭建PL端的以太网,以太网的PHY用的是Marvell的,那我就移动到Device Drivers—> Network device support —> Ethernet driver support —> Marvell devices,按下y将这个选项勾上;
然后用到了Xilinx的1g/2.5g Ethernet Subsystem,这个也要添加驱动,这个驱动的位置在Device Drivers—> Network device support —> Ethernet driver support —> Xilinx Devices ,默认是打开的,所以不需要更改;
接着按下左右键,移动光标到save上,保存配置到.config,再疯狂双击esc,双击数次后就能退出配置界面到命令行了;
退回Terminal后,输入下面的命令;
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage LOADADDR=0x8000
稍等片刻,等待编译完成,就能在/home/<用户名>/Downloads/linux-xlnx-xilinx-v2019.1/arch/arm/boot/下能看到生成的内核文件uImage。
将生成的uImage拷贝到/home/<用户名>/Documents/pl_ethernet里
四、SDK生成设备树和BOOT.bin
流程和上一篇的一模一样,请参考上一篇内容;
生成的文件的区别就是多了个pl.dtsi,内容是这样的;
/ {
amba_pl: amba_pl {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges ;
//这里描述的是1g/2.5g Ethernet Subsystem这个ip核的配置
axi_ethernet_0: ethernet@41000000 {
axistream-connected = <&axi_ethernet_0_dma>;
axistream-control-connected = <&axi_ethernet_0_dma>;
clock-frequency = <100000000>;
clock-names = "s_axi_lite_clk axis_clk gtx_clk ref_clk";
clocks = <&clkc 15>, <&clkc 15>, <&misc_clk_0>, <&misc_clk_1>;
compatible = "xlnx,axi-ethernet-7.1", "xlnx,axi-ethernet-1.00.a";
device_type = "network";
interrupt-names = "mac_irq interrupt";
interrupt-parent = <&intc>;
interrupts = <0 29 1 0 30 4>;
local-mac-address = [00 0a 35 00 00 00];//eth1的mac地址
phy-mode = "rgmii";
reg = <0x41000000 0x10000>;
xlnx = <0x0>;
xlnx,axiliteclkrate = <0x0>;
xlnx,axisclkrate = <0x0>;
xlnx,clockselection = <0x0>;
xlnx,enableasyncsgmii = <0x0>;
xlnx,gt-type = <0x0>;
xlnx,gtinex = <0x0>;
xlnx,gtlocation = <0x0>;
xlnx,gtrefclksrc = <0x0>;
xlnx,include-dre ;
xlnx,instantiatebitslice0 = <0x0>;
xlnx,phy-type = <0x3>;
xlnx,phyaddr = <0x1>;
xlnx,phyrst-board-interface-dummy-port = <0x0>;
xlnx,rable = <0x0>;
xlnx,rxcsum = <0x0>;
xlnx,rxlane0-placement = <0x0>;
xlnx,rxlane1-placement = <0x0>;
xlnx,rxmem = <0x1000>;
xlnx,rxnibblebitslice0used = <0x0>;
xlnx,tx-in-upper-nibble = <0x1>;
xlnx,txcsum = <0x0>;
xlnx,txlane0-placement = <0x0>;
xlnx,txlane1-placement = <0x0>;
axi_ethernet_0_mdio: mdio {
#address-cells = <1>;
#size-cells = <0>;
};
};
//这里是两个由Clock Wizard生成的时钟,一个125M,1个200M
misc_clk_0: misc_clk_0 {
#clock-cells = <0>;
clock-frequency = <125000000>;
compatible = "fixed-clock";
};
misc_clk_1: misc_clk_1 {
#clock-cells = <0>;
clock-frequency = <200000000>;
compatible = "fixed-clock";
};
//以太网ip外面自动配置上的DMA的配置
axi_ethernet_0_dma: dma@40400000 {
#dma-cells = <1>;
axistream-connected = <&axi_ethernet_0>;
axistream-control-connected = <&axi_ethernet_0>;
clock-names = "s_axi_lite_aclk m_axi_sg_aclk m_axi_mm2s_aclk m_axi_s2mm_aclk";
clocks = <&clkc 15>, <&clkc 15>, <&clkc 15>, <&clkc 15>;
compatible = "xlnx,eth-dma";
interrupt-names = "mm2s_introut s2mm_introut";
interrupt-parent = <&intc>;
interrupts = <0 31 4 0 32 4>;
reg = <0x40400000 0x10000>;
xlnx,include-dre ;
};
};
};
将生成的BOOT.bin拷贝到/home/<用户名>/Documents/pl_ethernet里
五、设备树的生成
将SDK(Windows环境)生成的设备树文件夹传入虚拟机中;
修改system-top.dts的内容;
原内容为:(注意还是有格式的问题)
/dts-v1/;
#include "zynq-7000.dtsi"
#include "pl.dtsi"
#include "pcw.dtsi"
/ {
chosen {
bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=0 earlycon";
stdout-path = "serial0:115200n8";
};
aliases {
ethernet0 = &gem0;
ethernet1 = &axi_ethernet_0;
serial0 = &uart1;
spi0 = &qspi;
};
memory {
device_type = "memory";
reg = <0x0 0x20000000>;
};
};
修改为:
/dts-v1/;
/include/ "zynq-7000.dtsi"
/include/ "pl.dtsi"
/include/ "pcw.dtsi"
/ {
chosen {
bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=0 earlycon";
stdout-path = "serial0:115200n8";
};
aliases {
ethernet0 = &gem0;
ethernet1 = &axi_ethernet_0;
serial0 = &uart1;
spi0 = &qspi;
};
memory {
device_type = "memory";
reg = <0x0 0x20000000>;
};
};
//添加关于pl以太网的节点描述,仅供参考
&axi_ethernet_0 {
phy-handle = <&phy0>;
xlnx,has-mdio = <0x1>;
phy-mode = "rgmii-rxid";
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy0: phy@0 {
device_type = "ethernet-phy";
reg = <0>;
};
};
};
然后在这个文件夹下,右键单击空白处,选择open Terminal进入命令行,输入下面命令;
dtc -I dts -O dtb -o devicetree.dtb system-top.dts
就能在文件夹下看到生成的devicetree.dtb了。
将生成的devicetree.dtb拷贝到/home/<用户名>/Documents/pl_ethernet里
六、linaro文件系统
具体流程还是和上一篇一样,只不过制作过SD卡的就不需要动第二分区(EXT4)的文件了,只需要将第一分区(FAT32)的三个启动文件替换为/home/<用户名>/Documents/pl_ethernet下的三个文件即可。
七、系统启动
现在把SD卡插到开发板的SD卡插槽中,连接USB串口,上电启动。
在putty中设置串口的参数(串口名在设备管理器中查看,波特率为115200)就可以看到系统正常启动了。
并能看到新增的以太网模块;