此实验仅限于Linux内核及根文件系统移植及网络调试,ZYNQ涉及FPGA硬件电路设计部分,还需要Vivado软件生成硬件设计文件(.hdf),并基于Petalinux制作BOOT.BIN,才能使用FPGA硬件电路。
限于Uboot网络调试,还不能高效关联BOOT.BIN,因此我觉得网络调试只能基于ZYNQ PS ARM A9内核调试Linux和根文件系统。后续我会进一步思考如何在UBoot中实现关联FPGA部分(比如:启动,下载等),实现和Linux内核的关联,加快开发效率
1 前置条件准备
1.1 kernel 和uboot安装包准备
- ZYNQ 开发板资料盘(A盘 )\4_SourceCode\3_Embedded_Linux\ 资 源 文 件 \kernel\linux-xlnx-xilinx-v2018.3.tar.gz。
- Xilinx 提供的 Linux 源码肯定可以在 Xilinx 的 ZYNQ EVK 开发板上运行的,我们以 ZYNQ EVK 开发板为参考,然后将 Linux 内核移植到我们的 ZYNQ 小系统板上
- 笔者工作目录
work3-yuanshenglinuxyizhi中存放Xilinx 提供的 Linux 源码linux目录中关键的主要是:nfs 实现根文件系统网络挂载,tftpboot实现zImage与zynq-alientek.dtb网络下载
参考脚本:
mkdir -p ~/work/linux-4.14 //创建目录
tar -xzf alientek-linux-4.14.0-xlnx-v2018.3.tar.gz -C ~/work/linux-4.14/ //解压
sync //同步
rm -rf alientek-linux-4.14.0-xlnx-v2018.3.tar.gz //删除压缩包文件
mkdir ~/work/uboot-2018.01
tar -xzf alientek-uboot-2018.01-xlnx-v2018.3.tar.gz -C ~/work/uboot-2018.01/
sync
rm -rf alientek-uboot-2018.01-xlnx-v2018.3.tar.gz
2 NFS文件系统搭建
- 文件系统NFS网络挂载及网络调试
sudo apt-get install nfs-kernel-server rpcbind
sudo vi /etc/exports
/home/qinkaixin/linux/nfs *(rw,sync,no_root_squash)
- Linux网络下载镜像时“nfs报错:ERROR: File lookup fail”解决方法,导致此错误得原因是:uboot中使用得NFS版本为V2版本,而ubuntu中的NFS版本为V3,V4及以上版本,从而导致uboot不能再NFS服务器中找到文件。
cat /etc/default/nfs-kernel-server
RPCNFSDCOUNT="-V 2 8"
RPCNFSDPRIORITY=0
RPCMOUNTDOPTS="-V 2 --manage-gids"
NEED_SVCGSSD=""
RPCSVCGSSDOPTS="--nfs-version 2,3,4 --debug --syslog"
sudo service nfs-kernel-server restart
NFS 功能:
nfs C2000000 192.168.0.111:/home/***/linux/nfs/rootfs/test
3 Xilinx 官方开发板 Linux 内核编译
3.1 修改顶层 Makefile
3.2 配置并编译Linux内核
3.3 添加开发板对应的设备树文件
- Linux 支持设备树,每个开发板都有一个对应的设备树文件。Xilinx 的 ZYNQ 系列芯片的所有设备树文件夹都存放在arch/arm/boot/dts 目录下,在这个目录下有个名为 zynq-zc702.dts 的文件,该文件是
ZC702 开发板的设备树文件。 - 将 zynq-zed.dts 重命名为 zynq-alientek.dts,命令如下:
cd arch/arm/boot/dts
cp zynq-zed.dts zynq-alientek.dts
3.4 修改设备树
- 笔者在此处遇到很多问题,归根到底还是设备树修改的问题,主要就是串口部分,注意将文件中的“uart1”全部替换为“uart0”
vim arch/arm/boot/dts/zynq-alientek.dts
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2011 - 2015 Xilinx
* Copyright (C) 2012 National Instruments Corp.
*/
/dts-v1/;
#include "zynq-7000.dtsi"
/ {
model = "Zynq Alientek Development Board";
compatible = "xlnx,zynq-alientek", "xlnx,zynq-7000";
aliases {
ethernet0 = &gem0;
serial0 = &uart0;
spi0 = &qspi;
mmc0 = &sdhci0;
};
memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
chosen {
bootargs = "";
stdout-path = "serial0:115200n8";
};
usb_phy0: phy0@e0002000 {
compatible = "ulpi-phy";
#phy-cells = <0>;
reg = <0xe0002000 0x1000>;
usb-reset = <&gpio0 9 0>;
view-port = <0x0170>;
drv-vbus;
};
};
&clkc {
ps-clk-frequency = <33333333>;
};
&gpio0 {
emio-gpio-width = <7>;
gpio-mask-high = <0x0>;
gpio-mask-low = <0x5600>;
};
&uart0 {
u-boot,dm-pre-reloc;
status = "okay";
};
&gem0 {
status = "okay";
phy-mode = "rgmii-id";
phy-handle = <ðernet_phy>;
local-mac-address = [00 0a 35 00 1e 53];
ethernet_phy: ethernet-phy@0 {
reg = <0>;
device_type = "ethernet-phy";
};
};
- 需要注意的是这里的 zynq-alientek.dts 文件只是配置了 ZYNQ 的 PS 端,使 linux 内核能够启动,
PL 端并没有配置,如何配置 PL 端可以进入第九章的 Petalinux 工程,在工程的“components\plnx_workspace\device-tree\device-tree”目录下有很多 dts 文件,可以参考该目录下的 system-top.dts 文件(特别是该文件所 include 的文件)来配置 zynq-alientek.dts 文件。
3.5 修改设备树arch/arm/boot/dts/Makefile
- zynq-alientek.dts 修改好以后我们还需要修改文件 arch/arm/boot/dts/Makefile,找到
“dtb-$(CONFIG_ARCH_ZYNQ)”配置项,在此配置项中加入“zynq-alientek.dtb\” ,如下所示:
3.5 内核及设备树编译
- 内核编译
#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- alientek_zynq_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
- 如果后面测试的时候只修改设备树的话可只重新编译设备树,在 Linux 内核源码根目录下输入如下命令编译设备树:
make dtbs
4 拷贝设备树与Linux内核uImage到tftp
cp arch/arm/boot/zImage /home/qinkaixin/linux/tftpboot
cp arch/arm/boot/dts/zynq-alientek.dtb /home/qinkaixin/linux/tftpboot
5 根文件系统
- 拷贝根文件系统到nfs中
6 网络开发环境调试
6.1 uboot IP设置
setenv ipaddr 192.168.0.105
setenv ethaddr b8:ae:1d:01:01:01
setenv gatewayip 192.168.0.1
setenv netmask 255.255.255.0
setenv serverip 192.168.0.124
saveenv
6.2 uboot设置nfs根文件系统
- 启动开发板,进入 uboot 命令行模式,然后重新设置 bootargs 环境变量,命令如下
setenv bootargs 'console=ttyPS0,115200 root=/dev/nfs nfsroot=192.168.0.124:/home/qinkaixin/linux/nfs/,tcp ip=dhcp rw'
saveenv
6.3 tftp网络调试
setenv bootcmd 'tftpboot 8000 zImage; tftpboot 103cdda8 zynq-alientek.dtb; bootz 8000 - 103cdda8'
saveenv
boot