这篇博文讲述的是在Linux环境下,将生成的新BOOT.BIN利用dd指令写入板上qspi flash中。板子从flash启动后,转至SD卡执行linux内核。这篇博文是为了之后不使用SD卡,将linux内核以及根文件系统放入emmc启动做准备。
目录
2 - 建立新的"BOOT_FOR_QSPIFLASH.BIN"
3 - 利用SD卡上运行的linux系统烧录新的BOOT.BIN到FLASH中
0 - 前言
前面我们使用petalinux制作linux从板子上启动都是从SD卡(TF卡)启动的,但是在绝大部分的应用场景中,使用SD卡作为存储载体明显不是一个很好的选择。为了探究如何摆脱SD卡的存储方式,这篇博文记载了些实验性的研究。
ZYNQ的上电启动其实可以分为三个部分:BootROM、FSBL(First Stage Boot Loader)以及用户程序。这里用户程序可能是裸机程序,或者其他更“高级”操作系统的BootLoader,对于linux来说这里就是uboot。
这里我们不细谈上电启动,感兴趣的可以参考xilinx的XAPP1158,是讲解vxworks在zynq上的部署方法,但是前半部分讲解了zynq的启动流程。我们知道,在使用petalinux生成linux时,执行petalinux-package后会生成两个文件,一个BOOT.BIN,一个是image.ub,根据你给的指令,会打包不同的文件进入BOOT.BIN。这里我们以下面这个命令举例:
petalinux-package --boot --fsbl --fpga --u-boot --force
执行这条语句,会将FSBL、比特流文件(PL端配置程序)及uboot打包为BOOT.BIN文件。当ZYNQ上电启动后,先执行固化在内部的BootROM程序,初始化NAND、NOR、Quad-SPI、SD以及PCAP。BootROM执行完毕后,会将FSBL加载到OCM(On Chip Memory)然后执行FSBL。FSBL中会用比特流文件对PL部分编程,初始化DDR,然后将用户程序(uboot)拷贝到DDR来执行。这里可以看到,FSBL以及我们的UBOOT其实是被打包在了BOOT.BIN文件中,而我们的linux内核,linux根文件系统则可以在其他的地方,只要告诉uboot执行时跳转到哪里调用linux内核即可。
因此,我们为了使用板载的“固态”存储器来启动linux系统,我们有两种方法来完成这个操作:
- BOOT.BIN放置在QSPI Flash中,linux内核(image.ub)、linux根文件系统放置在emmc中。选择从QSPI启动
- BOOT.BIN、image.ub以及根文件系统都放置到emmc中。选择从emmc启动
那么就有一个问题,我们要如何将BOOT.BIN、image.ub以及根文件系统分别放置到flash和emmc中呢?因为这些板载的存储器并不像sd卡或者tf卡一样可以直接使用读卡器从电脑上进行读写。有一种方便的方法就是用已经在sd卡中搭建好的linux来对这些flash和emmc进行操作。
下面以将BOOT.BIN写入FLASH中,uboot唤起SD卡中的image.ub做个例子。为啥不做emmc的?因为我新买的板子还没到,手头这个板子没得emmc。
注:zynq7000系列不支持将emmc作为第一启动设备,即不支持从emmc读取BOOT.BIN中的FSBL,ultrascale系列支持这项操作。
参考:
- https://www.xilinx.com/support/answers/50991.html
- 《UG585- Zynq-7000 SoC Technical Reference Manual 》中 11.2.1 Boot Device
1 - 准备工作
一块已经能从sd卡跑linux的,板上有QSPI FLASH,并且vivado建立工程时已经连接好这个flash,petalinux生成的linux(或者包含好了qspi flash驱动的linux)的一块fpga板卡。
2 - 建立新的"BOOT_FOR_QSPIFLASH.BIN"
打开之前的工程(可以参考之前的博客https://blog.csdn.net/sements/article/details/88921275#6%20-%20%E7%94%9F%E6%88%90BOOT.BIN%E5%8F%8Aimage.ub%E6%96%87%E4%BB%B6),运行下面的指令进行petalinux的配置
petalinux-config
在打开的页面中,修改下列的选项
- 设置boot image settings存储媒介为primary flash(即我们板上的QSPI FLASH)
- 设置kernel image settings存储媒介为primary sd
#Subsystem AUTO Hardware Settings --->
# Advanced bootable images storage Settings --->
# boot image settings --->
# image storage media ---> primary flash
# kernel image settings --->
# image storage media ---> primary sd
题外话:zynq支持两个SD/SDIO外设,可以接SD卡或者emmc芯片。当两者都在硬件设计上存在时,接在SD0上的设备在/dev中显示为mmcblk0,SD1上的显示为mmcblk1。这里不需要考虑,因为我板上没有添加emmc硬件,只有sd卡硬件,但是当后面两者同时存在时,则需要在SD/SDIO Settings 配置项中指定主要的SD外设。
参考【 】CH10 调整EMMC和SD的挂载顺序并且实现开机自动烧录QSPI - LINUX教程(2018) 米联客 http://www.osrc.cn/forum.php?mod=viewthread&tid=1647&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline
重新编译:
petalinux-build
编译完成后,我们打包生成BOOT.BIN
petalinux-package --boot --fsbl --fpga --u-boot --force
从images/linux文件夹下拷贝出BOOT.BIN备用。
3 - 利用SD卡上运行的linux系统烧录新的BOOT.BIN到FLASH中
将新的BOOT.BIN拷贝到正在运行的SD卡上的linux系统中(可以用sftp传输)。
打开/dev文件夹,查看FLASH:
ls /dev
可以看到,这里mtd开头的即是我们板上的flash了,我们接下来需要将新的BOOT.BIN写入到mtdblock0中即可
dd if=新的BOOT.BIN of=/dev/mtdblock0
写入完毕后,poweroff关机linux,将开发板启动模式选择为QSPI,将SD卡拔出,上电,我们可以看到以下的调试信息
U-Boot 2018.01 (Apr 28 2019 - 12:58:04 +0000) Xilinx Zynq ZC702
Model: Zynq ALINX Development Board
Board: Xilinx Zynq
Silicon: v3.1
I2C: ready
DRAM: ECC disabled 512 MiB
MMC: Card did not respond to voltage select!
mmc_init: -95, time 23
mmc@e0100000 - probe failed: -95
Card did not respond to voltage select!
mmc_init: -95, time 24
SF: Detected w25q256 with page size 256 Bytes, erase size 4 KiB, total 32 MiB
*** Warning - bad CRC, using default environment
In: serial@e0001000
Out: serial@e0001000
Err: serial@e0001000
Model: Zynq ALINX Development Board
Board: Xilinx Zynq
Silicon: v3.1
Net: ZYNQ GEM: e000b000, phyaddr 1, interface rgmii-id
eth0: ethernet@e000b000
U-BOOT for alinx_linux_base
ethernet@e000b000 Waiting for PHY auto negotiation to complete...... done
BOOTP broadcast 1
DHCP client bound to address 192.168.2.54 (8 ms)
Hit any key to stop autoboot: 0
Card did not respond to voltage select!
mmc_init: -95, time 23
** Bad device mmc 0 **
no mmc device at slot 0
Zynq>
说明已经正常的从QSPI FLASH中加载新的BOOT.BIN,并运行uboot了,只是这里由于我将SD卡拔出,所以"no mmc device at slot0"
断电,将带有image.ub的SD卡插入,重新上电(还是从QSPI启动),可以看到以下调试信息
可以看到linux系统已经正常的跑起来了。