1 背景
使用黑金开发板,全部开发流程避开使用SD卡调试,zynq开发过程中很多资料都是基于SD启动。这样就对新板卡调试带来了一定的困难,因为新板卡基本上没有设计SD卡。这里就一步一步实现qspi启动内核,格式化分区emmc,挂载emmc分区文件系统。
这里需要综述一下调试思路:
- 第一步:根据原理图搭建最小系统vivado工程,使用SDK对硬件电路进行测试
- 第二步:根据vivado工程的hdf文件,使用petalinux生成设备树文件
- 第三步:调试U-boot,这需要调试U-boot设备树、W25Q256FVEI、KSZ9031驱动,tftpboot 指令、bootz指令,NFS挂载文件系统。U-boot调试是重点,能够通过U-boot NFS挂载文件系统,板卡启动后,进行emmc的格式化分区,制作文件系统,再同通过修改环境变量、bootargs设置启动挂载emmc分区。
- 第四步:调试kernel,配置KSZ9031驱动
- 第五步:调试kernel用设备树
这里需要解释一下为什么没有采用petalinux一站式调试,petalinux对U-boot、kernel封装的很好,但是实际调试过程中很不方便,不够灵活。最难以忍受的是QSPI生成的BOOT.BIN文件把内核、设备树、bit流都打包进去,一下子十多兆,用仿真器烧录进去,都要好久,调试过程呢这个烧录反反复复,大大降低了调试效率。当然还有其他问题,比如u-boot、设备树、内核、bit流的修改不够灵活,效率太低。
最终实现效果如下图所示:
最终软件部署图
本文调试过程使用Vivado工程,Uboot源码,Kernel源码,步骤文档等等如下链接
zynqqspi启动、无SD卡、调试全过程,含vivado工程,使用Uboot源码,使用Kernel源码等调试过程使用资源资源-CSDN文库
2 原理图
这里选用的黑金开发板,黑金开发板底版上是有设计SD卡的,这里我们就是要避开使用SD卡,所以关于SD卡的设计部分,我们就默认为不存在。
2.1 QSPI
这里部分原理图QSPI采用W25Q256FVEI
2.2 emmc
emmc采用MTFC8GAKAJCN型号。这里需要注意的是这里对的emmc连接到PS的控制器SD1上了。
2.3 DDR
ddr设计1G空间,图太多,就不贴了。
采用型号MT41K256M16TW,在开发板的核心板原理图中有详细的原理图设计。
2.4 串口
调试串口
使用ps端串口1,黑金开发板串口0在核心板上,底版是串口1,我们使用底版的串口进行调试,所以这里要重点关注,尤其是Uboot中,不然会看不到打印数据。
2.5 网口
采用片上PS 端MAC0,通过RGMII接口连接采用PHY KSZ9031RNX,phy的地址为0x01,这里注意后面写设备树需要。Uboot需要移植一下该PHY的驱动,内核也是需要的,图太多,就不贴了。
3 Vivado工程
Vivado 采用2018.3。vivado搭建最小系统,这需要注意的是
BANK电压的选择
DDR控制器的选择,根据使用DDR的型号选择
emmc连接到SDIO1
vivado工程不做过多的设计,这里主要是把系统调试通,后面vivado工程,可以随时更新。
BD文件,这里很简单,主要是一些PS侧的一些设置。
附件资料提供vivado工程。
4 SDK
4.1 硬件调试
新板子贴装回来,硬件工程师一般先对电源电路进行调试,保障板子不爆炸,哈哈,然后丢给软件人员。有些NB的硬件工程师,自己可以使用SDK跑一些测试例程测试一下硬件的基本电路。
这里SDK测试硬件电路不是文章的重点,SDK新建工程也比较简单,如下图所示,SDK提供了很多测试例程,不懂C语言都可以进行测试,这里就不过多阐述。
举例说明,跑一下SDK的串口例程,看看串口打印是否正常,如果串口打印不正常,检查串口电路是否正常,收发是否反接了等等问题。
SDK提供用于测试的例程
4.2 FSBL
这里我们要新建一个FSBL工程,用来挂着仿真器,下载BOOT.BIN到QSPI FLASH(BOOT.BIN文件的制作参考5、6、7章节)
烧录步骤如下:
- 板子掉电,连接仿真器到电脑,设置JATG启动,板子上电
- SDK配置选择如下图所示
- 烧录成功提示log如下
- 板子掉电,设置QSPI启动,板子上电,看一下串口输出
附件资料提供SDK工程
5 Petalinux
Petalinux采用2018.03版本。
Vivado工程到导出HDF文件,使用petalinux生成bit文件、设备树文件,供后续使用。具体步骤如下
创建文件夹
mkdir -p work/petalinux/
打开文件夹
cd work/petalinux/
有效petalinux环境变量
source /opt/petalinux/settings.sh
创建工程
petalinux-create -t project --template zynq -n zynq_linux
cd zynq_linux
配置hdf文件,该hdf文件,由上述vividao工程生成,这里弹出配置界面,我们全部保留默认配置即可。这里配置需要一段时间,需要耐心等待。
petalinux-config --get-hw-description /media/ltt/019e0de3-9402-4e53-83f4-f86198f1464d2/ALINX/work/hdf/
编译,这里编译需要一段时间,需要耐心等待。
petalinux-build
需要注意的是petalinux使用过程完全保持默认配置,因为我们仅仅需要petalinux打包生成BOOT.BIN。
5.1 制作BOOT.BIN
打包生成BOOT.BIN,注意如下指令,仅仅将u-boot.elf和zynq_fsbl.elf打包到BOOT.BIN内,这样BOOT.BIN的大小就很小,一般不到1M,使用仿真器烧录进QSPI就非常快。下列指令,是我们使用Petalinux的主要目的
petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --u-boot --force
这里只是告诉我们怎么制作BOOT.BIN,这个BOOT.BIN还不能直接烧录到黑金开发板,我们要对Uboot做第6、7章节的更改后,再烧录进去调试。
6 设备树
这里为什么要提前写设备树相关的内容呢,因为设备树再Uboot和内核中都有涉及。其中Uboot的设备树可以相对简单一些。
在第5章中文件夹,在 Petalinux 工 程 中 执 行 编 译 uboot 后 , 会 在 工 程 的components/plnx_workspace/device-tree/device-tree/目录下生成设备树文件,如下图所示
根据上述文件的四个文件的基础修改自己的设备树文件。
7 Uboot
Uboot调试时整个调试过程中最关键,这里我们选择u-boot-xlnx-xilinx-v2018.3。
Xilinx 维护的 uboot 版本可在网站 https://github.com/Xilinx/u-boot-xlnx 查看。Uboot调试过程需要反复烧录QSPI,具体流程如下
- 修改uboot
这里修改内容就比较多,包含修改配置,修改代码,添加驱动、修改设备树等等操作
- 编译uboot
- 替换第5章Petaliux中./images/linux/u-boot.elf文件
- 执行指令,生成新的BOOT.BIN
- 将新的BOOT.BIN烧录板子,进行测试,如果有问题重复步骤1
配置文件修改,我们直接在Xilinx 官方的 ZYNQ ZC702 开发板做的硬件进行修改
7.1 Uboot添加QSPI驱动W25Q256FVEI
这个版本的Uboot是有W25Q256FVEI驱动的,需要进行配置一下,具体为:
在zynq_zc702_defconfig文件追加如下配置
CONFIG_SPI_FLASH_WINBOND=y
这里zynq_zc702_defconfig文件中已经配置该项,所以无需进行任何改动。正确识别到SPI FLASH的打印log如下图所示
7.2 Uboot添加KSZ9031驱动
这个版本的Uboot是有KSZ9031驱动的,需要进行配置一下,具体为:
在zynq_zc702_defconfig文件追加如下配置
CONFIG_PHYLIB=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
我尝试了一下,在没有进行上述配置的清空下也能ping通,这里为了保险起见,还是添加上述配置。
7.3 Uboot修改设备树
在zynq_zc702_defconfig文件修改如下代码
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
修改为
CONFIG_DEFAULT_DEVICE_TREE="system-top"
修改arch/arm/dts/Makefile
在如 内容结尾处字段追加 system-top.dtb
dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-cc108.dtb \
zynq-cse-nand.dtb \
zynq-cse-nor.dtb \
zynq-cse-qspi-parallel.dtb \
zynq-cse-qspi-single.dtb \
zynq-cse-qspi-stacked.dtb \
zynq-cse-qspi-x1-single.dtb \
zynq-cse-qspi-x1-stacked.dtb \
zynq-cse-qspi-x2-single.dtb \
zynq-cse-qspi-x2-stacked.dtb \
zynq-microzed.dtb \
zynq-picozed.dtb \
zynq-syzygy-hub.dtb \
zynq-topic-miami.dtb \
zynq-topic-miamilite.dtb \
zynq-topic-miamiplus.dtb \
zynq-zc702.dtb \
zynq-zc706.dtb \
zynq-zc770-xm010.dtb \
zynq-zc770-xm011.dtb \
zynq-zc770-xm012.dtb \
zynq-zc770-xm013.dtb \
zynq-zed.dtb \
zynq-zturn-myir.dtb \
zynq-zybo.dtb \
system-top.dtb
将第6章中四个设备树文件复制到arch/arm/dts文件夹下,并修改system-top.dts文件,具体修改内容如下:
文件增加了网口的设备树、QSPI的设备,以及指定了打印串口1,设备的对比第6章自动生成设备文件改动较小。system-top.dtsi文件如下
/*
* CAUTION: This file is automatically generated by Xilinx.
* Version:
* Today is: Thu Jun 13 08:06:37 2024
*/
/dts-v1/;
#include "zynq-7000.dtsi"
#include "pcw.dtsi"
/ {
model = "ALINX Board 333";
compatible = "xlnx,zynq-7000";
chosen {
bootargs = "console=ttyPS1,115200 earlyprintk root=/dev/mmcblk0p2 rw rootwait";
stdout-path = "serial1:115200n8";
};
aliases {
ethernet0 = &gem0;
serial0 = &uart1;
spi0 = &qspi;
mmc0 = &sdhci1;
};
memory {
device_type = "memory";
reg = <0x0 0x40000000>; // DDR size
};
};
&gem0 {
phy-handle = <ðernet_phy>;
local-mac-address = [00 0a 35 00 1e 53];
ethernet_phy: ethernet-phy@1 {
reg = <0x1>;
device_type = "ethernet-phy";
};
};
&uart0 {
u-boot,dm-pre-reloc;
status = "okay";
};
&uart1 {
u-boot,dm-pre-reloc;
status = "okay";
};
7.4 制作BOOT.BIN
修改后的Uboot编译通过后,生成u-boot
编译指令如下
使能环境变量
source /opt/petalinux/settings.sh
清理Uboot
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
生成.config
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zynq_zc702_defconfig
编译Uboot
make V=0 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8
将该u-boot修改为u-boot.elf,复制到5.1中/images/linux/文件夹下,然后执行5.1中命令,生成BOOT.BIN。
使用该BOOT.BIN文件参考4.2中烧录方法,下载到QSPI FLASH进行调试,通过调试串口,打印log信息判断目前烧录的BOOT,BIN的状态,如果网口或者QSPI驱动还有问题,要进一步修改,重复烧录调试。
使用SDK烧录配置:
烧录成功后,掉电,切换开启启动SPI启动,同通过串口查看打印信息。
7.5 测试
开机log发现,我们上述的修改都正确了。这里需要测试一下网口是否能够ping通,网口能够ping通。
这里要调试后一定要保证网口、QSPI FALSH正常,才能进行下面的操作。
8 Kernel
使用 Xilinx 提供的 Linux源码, Xilinx 提供的 Linux 源码,如下网址可以下载,使用
https://github.com/Xilinx/linux-xlnx/tree/xilinx-v2018.3
8.1 zImage
前面的过程太复杂了,新板调试的关键就是Uboot,这里内核,我们就不修改任何东西,直接编译zImage。在编译 Linux 内核之前要先配置 Linux 内核。每个板子都有其对应的默认配置文件,这些默认配置文件保存在 arch/arm/configs 目录中。 xilinx_zynq_defconfig 作为 ZYNQ EVK 开发板所使用的默认配置文件。
编译kernel,制作zImage
source /opt/petalinux/settings.sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage -j10
8.2 设备树
设备树可以参考7.3中Uboot修改设备树的方法。
编译设备树文件,这里将Uboot中使用的设备树文件,拷贝到./linux-xlnx-xilinx-v2018.3/arch/arm/boot/dts文件夹下
同时,修改./linux-xlnx-xilinx-v2018.3/arch/arm/boot/dts/Makefile添加system-top.dtb,如下所示:
dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-cc108.dtb \
zynq-microzed.dtb \
zynq-parallella.dtb \
zynq-zc702.dtb \
zynq-zc706.dtb \
zynq-zc770-xm010.dtb \
zynq-zc770-xm011.dtb \
zynq-zc770-xm012.dtb \
zynq-zc770-xm013.dtb \
zynq-zed.dtb \
zynq-zybo.dtb \
system-top.dtb
编译生成system-top.dtb,如下指令
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- system-top.dtb -j10
至此我们得到两个文件:
Linux 内核镜像文件: zImage。
Xilinx对应的设备树文件: system-top.dtb。
将这两个文件拷贝到tftp文件夹下,为后续tftp调试准备
9 TFTPBOOT
首先调试板卡和虚拟机Ubuntu之间,在 Ubuntu 上搭建 TFTP 服务器。关于搭建步骤网上资料较多,这里就不在重复。
使用电脑直接连接开发板,虚拟机Ubuntu作为服务器,需要配置一些参数,才能正常工作。
9.1 Ubuntu配置参数
这里保障虚拟机Ubuntu ping通,需要关闭电脑wifi虚拟机配置IP,本地电脑的IP也要保持和开发板、虚拟机Ubuntu的IP在同一网段。
sudo ifconfig ens33 192.168.3.99
9.2 Uboot配置参数
主要是配置板卡IP,配置服务器IP
setenv ipaddr 192.168.3.101
setenv ethaddr 00:0a:35:00:1e:53
setenv gatewayip 192.168.3.1
setenv netmask 255.255.255.0
setenv serverip 192.168.3.99
saveenv
9.3 tftpboot
需要将第8章中编译的文件,拷贝到tftpboot文件夹下
将文件通过tftpboot指令拷贝到DDR
tftpboot 0x2080000 zImage
tftpboot 0x2000000 system-top.dtb
启动内核
bootz 0x2080000 - 0x2000000
执行上述指令,启动内核,但是我们到这里还没有制作文件系统,所以这里启动内核会发生错误。但是如果内核能够正常启动,说明我们的Uboot调试告一段落了。
9.4 测试
测试过程中出现如下Starting kernel ...字样后,就没有任何提示信息了,该字样时Uboot打印,已经跳转到kernel,应该是时Kernel的打印串口切换到串口0了,也就是Uboot给到Kernel的bootargs需要修改
错误问题
Zynq> bootz 0x2080000 - 0x2000000
## Flattened Device Tree blob at 02000000
Booting using the fdt blob at 0x2000000
Loading Device Tree to 1fffa000, end 1ffff574 ... OK
Starting kernel ...
解决办法
Uboot中修改bootargs变量
setenv bootargs 'console=ttyPS0,115200 earlyprintk root=/dev/mmcblk0p2 rw rootwait'
saveenv
这里多说一句,bootargs中使用ttyPS0还是ttyPS1其实和设备树的写法也是相关的,实在不行就两者都试试了。总有一个是可以的。
这里内核能启动起来,恭喜你,三巨头你已经不知不觉中搞定了2个了,还有一个就是文件系统。
10 NFS文件系统
NFS的搭建,参考网上资料,比较多了,这里不再重复,也比较简单。
这里想说说为什么要搭建NFS文件系统,首先NFS方便调试,这个大家都知道。但是,你有没有想过,你的板卡刚从贴装厂出来,里面的EMMC啥数据都没有,你不可能直接把数据烧录到EMMC,当然这时有设计SD卡肯定更方便一些,多一种途径操作EMMC。
通过NFS的文件系统,我们就可以将EMMC格式化、分区、然后再进行挂载。
文件系统的制作,这里其实已经有了,Petalinux已经为我们生成了,可以使用,在/work/petalinux/zynq_linux/images/linux目录下
10.1 解压缩文件系统
解压缩文件系统,到该路径xxx/linux/nfs
mkdir rootfs
tar -xzvf /xxx/images/linux/rootfs.tar.gz -C /xxx/nfs/rootfs/
10.2 修改Uboot启动参数
首先我这里是电脑的网口直接连接开发板的网口,虚拟机Ubuntu ip地址配置为99,电脑win10的IP配置为100,开发板的IP配置为99
setenv bootargs 'console=ttyPS0,115200 root=/dev/nfs rw nfsroot=192.168.3.99:/xxx/nfs/rootfs ip=192.168.3.101:192.168.3.99:192.168.3.1:255.255.255.0::eth0:off'
saveenv
修改上述配置后,再进行第9章,启动内核后就可以,直接挂载NFS文件系统启动了。
10.3 测试
这里的文件系统可能还缺少很多指令,不过通过Petalinux可以配置,如果你有之前的文件系统,那也可以直接使用。
- 挂载MMC对MMC进行分区格式化,再将文件系统解压缩的指定分区;
- 修改Uboot的bootargs指定根文件系统为MMC的分区;
- 最后调试没有问题了,就可以固定Uboot的启动流程,将第9章中的手动启动指令,修改为自动启动。
11 总结
文章详解了qspi调试的全过程。后续关于文件系统的制作讲述有点粗糙,只是提出了步骤。不然文章太长,步骤过于复杂,会让初学者失去兴趣。
整个调试过程也可以看到,基于赛灵思官方ZYNQ ZC702 开发板的配置基本上不用修改都可以把整个过程调试通过。
这里提供调试过程中的所有资料,包含vivado工程、调试后Uboot源码、调试后Kernel源码、文件系统等,供参考。
有问题,可以留言交流。
12 使用资源下载
本文调试过程使用Vivado工程,Uboot源码,Kernel源码,步骤文档等等如下链接
zynqqspi启动、无SD卡、调试全过程,含vivado工程,使用Uboot源码,使用Kernel源码等调试过程使用资源资源-CSDN文库