EBAZ4205是矿机的控制板,拆机后可以作为开发板使用,但是需要经过一些硬件上的改动。如果不是对FPGA或者ZYNQ硬件很熟悉话,建议还是不要浪费时间了。对于这块矿板硬件的改动,在下次的blog里专门讲一下。这次来说一说最近遇到的一个问题和解决方法,希望帮助有需要的朋友。
板子的默认启动模式是Nand Flash启动,网上有很多的教程是把启动模式改成SD卡启动,然后将启动镜像拷贝SD卡中。首先,这种方式是可行的、靠谱的,但是需要做一些改动,就是需要增加一个20K的电阻。
启动模式参考[1]中的Chapter 6: Boot and Configuration。
竟然板子默认的是Nand Flash启动,说明这种方式肯定也是可以调试的,而且1Gb(256MB)的Nand Flash运行一个裁剪的小一点的Linux肯定也是没问题的。那么问题就来了如何烧写Nand Flash呢?
在SDK中可以完成ZYNQ PL端bit文件的下载和PS端elf文件的下载,当然也可以对Nand Flash编程。在Vivado中完成系统的配置和PL部分的逻辑,然后到SDK中完成软件部分的开发,这一部分可以直接使用SDK提供的工程模板,几乎是不需要任何修改,直接运行就可以了。这一部分网上的教程也很多我就不提了。但是,一会要说一下生成FSBL。
制作启动镜像需要以下三个东西:
Partitions | 说明 |
---|---|
FSBL | 使用SDK的FSBL工程模板生成 |
Bit文件 | Vivado中Block Design生成的bit文件 |
应用程序代码 | 裸机程序或者uboot |
注意:Create Boot Image的时候,这三个文件的顺序不能错。
在SDK中 Program Flash 的时候,会出现以下错误:
Initialization done, programming the memory
BOOT_MODE REG = 0x00000004
WARNING: [Xicom 50-100] The current boot mode is NAND.
If flash programming fails, configure device for JTAG boot mode and try again.
Problem in running uboot
Flash programming initialization failed.
报错信息中提示,烧写Nand Flash的时候需要工作在JTAG启动模式,但是改硬件将启动模式改为JTAG,烧写完成之后还要在改回Nand Flash启动,这很明显是不可行的。
这里首先要插入一个科普知识了,ZYNQ相对于其他通用ARM处理器很特殊的地方就是 FSBL。FSBL(First Stage Bootloader)的作用就是配置PL和加载用户的应用程序,这是其他的通用处理器不需要的做的。在FSBL之前还有一个Stage-0 Boot,这个是大部分处理器都有的,固化在处理器的内部ROM中,上电复位之后,最先执行,负责检测启动模式、配置时钟和内存接口,并将bootloader复制到内存中,然后将处理器交给bootloader。
要想知道FSBL的具体工作流程,很简单,只需要仔细的阅读资料[2],UG821中详细的介绍了FSBL的启动流程和各种启动模式。这里面涉及到Secure Boot,加密和验证的过程比较复杂,可以关注Non-Secure Boot模式。这里我就不做搬运工了。
看完了UG821,接下来需要做的就是去阅读FSBL的源代码,这里大家一定不要有心里负担,FSBL部分的代码非常的少,也很简单,因为FSBL是运行在OCM(On-Chip-Memory)中,所以必须很精简、高效。
这里大致介绍一下:
(1)FSBL首先执行ps7_inti(),这个函数是根据Vivado在导出硬件描述文件(hdf文件实际是一个zip压缩包文件,解压后可看到内部的文件)生成的,ps7_init.c/ps7_init.h初始化DDR、MIO和SLCR寄存器;
(2)DDR读写测试,在0地址和1MB的位置,写入0xAA55AA55,然后读出比较;确认前1MB的内存存在;
(3)初始化PL配置接口,获取PCAP控制器的设置,检查是否使用了Secure-Boot加密;
(4)获取启动模式(通过读启动模式引脚电平),支持QSPI/EMMC、NAND、NOR、SD卡和JTAG启动模式;
(5)将启动镜像拷贝到DDR中,并返回镜像的起始地址,LoadBootImage方法会解析存储器中的Image Header Table以获取所有镜像的位置和信息,并且完成Secure-boot/Multiboot、加载bit配置到PL等任务,是FSBL的核心内容。
(6)跳转到第二阶代码继续执行,fsbl_handoff是通过汇编代码完成的,关闭ICache、DCache和MMU,并跳转到程序起始地址。
至此,FSBL完成。
SDK完成Nand Flash的烧写实际上时通过FSBL完成,首先这一点最开始是我猜的。因为在烧写Nand Flash的时候需要添加Image File和Flash Type以外,还需要指定一个FSBL。这个FSBL就是用来完成Nand Flash烧写的。所以,如果这个FSBL检测到启动模式不是JTAG就会报错。
然后我在Xilinx的官网问答中找到了这个内容,就证实了我的猜想。请参考
AR#56030 14.5 Zynq-7000 SoC AP iMPACT - NAND programming requires the board to be in JTAG mode
AR#56030中已经说的很清楚了,制作一个特殊的FSBL,通过修改一下代码
/*
* Read bootmode register
*/
// BootModeRegister = Xil_In32(BOOT_MODE_REG);
// BootModeRegister &= BOOT_MODES_MASK;
BootModeRegister = JTAG_MODE;
然后将生成的elf文件保存好,以后烧写Nand Flash的时候就用这个了。注意这个FSBL文件和生成Boot Image的FSBL不是同一个。如果你对ZYNQ的开发有一定的实际操作的话,就应该知道我在说什么了。
有了这个JTAG启动模式的FSBL就可以不修改启动模式,就烧写Nand Flash了。如果你也遇到了同样的问题,按照这个方法就可以解决了。
如果还有什么问题的话,可以给我留言。
[1] ug585-Zynq-7000-TRM.pdf
[2] ug821-zynq-7000-swdev.pdf