1,BOOT.BIN在哪里运行存储于启动模式,内部的BITSTREAM以及U-BOOT(或者用户APP)都可以存储。
2,UBOOT有启动命令脚本(auto booting).这个脚本指示从SD卡某个文件或者QSPI FLASH的某个地址区域取
KERNEL和DTB以及ROOTFS,保存在内存的指定区域(这个指定内存区域跟KERNEL编译时候的设置以及其他是对应的)。
3,KERNEL在内存指定位置运行,挂载的RAMDISK是指定在内存的固定区域里的。
分析SD卡启动和QSPI FLASH启动的差别,结合以上三点我们不难总结出:
1,文件系,DTB和内核都不需要修改,因为他是在固定的内存区域运行。UBOOT传递的启动参数指示跟文件系统,DTB位置也一样。
2,BOOT.bin里面的zynq_fsbl和bitstream都不需要变化。
3,UBOOT的启动脚本命令必须变化,之前是从SD指定文件取数据,现在是从QSPI FLASH的指定地址取数据。
综上我们只需要在UBOOT的自动启动脚本里面指示出来KERNEL,ROOTFS,DTB的存放位置就可以达到从QSPI FLASH启动的目的。而这三个文件都被集中放在image.ub这个文件里。我们在系统配置指示一下image存放位置就可以。
petalinux-config
选择Subsystem AUTO Hardware Setting.
选择Advanced bootable images storage settings.
进入后我们看到这里实际就是设置image.ub的存放区域。
我们看到默认是从SD启动,并且下一行指示出了文件名称是image.ub。我们点进去选择
选择primary flash。
之后就看到多了箭头所指示的这一行。说明image.ub是要存在qspi flash的kernel区。
这里跟qspi flash划分了多个区域,我们可以在
Subsystem AUTO Hardware Setting -> Flash Setting里面看到QSPI FLASH 的分区(当然也可以修改)。
我们看到
第一个区名称是boot,从地址0开始,长度是0x500000 .(是5M,7Z020的BITSTREAM是4M多一点,加上UBOOT,FSBL不到5M,因此足够)。
第二个区名称是bootnv,从地址0x500000开始,长度是0x20000 ,这里存放UBOOT启动参数或者命令。UBOOT启动后会检查这部分是否为有效的启动命令,如果是则执行这些有效的命令,如果不是则执行autoboot(32K)。我们现在接触到的都是不设置这部分而自动运行autoboot.
第三部分名称是kernel,从地址0x520000开始,长度可以32M-0x52000,长度大于26M的样子。当然这26M还可以继续划分成两个或者三个分区还可以继续划分分区。这里就是image.ub的。
这里我们看之前有parttion0,1,2,3 的字样,我们就要明白这在linux系统里面对应的设备是/dev/mtd*,*就是0,1,2,3。
我们在linux将文件a.bin拷贝到qspi flash 的kernel区的话,首先找到kernel 所在区为2,对应的linux设备是mtd2
之后执行flash拷贝命令
flashcp a.bin /dev/mtd2
之后输入pealinux-build ,进行编译。
在image/linux目录下生成了u-boot.elf,zynq_fsbl,system.bin 以及image.ub。这些文件中实际上跟sd卡启动的petalinux设置唯一差别的文件就是u-boot.elf,而这个文件的差别也仅仅在于autobooting的脚本(是指示从qspi flash的指定地址0X52000获取image.ub而不是从sd卡的指定文件名)
生成boot.bin后,烧写到flash的0x0的boot分区(对应linux下的/dev/mtd0)。而将image.ub烧写到0x520000的kernel分区(对应/dev/mtd2)。这里烧写步骤有多种,可以用SDK,也可以用 tftp下载到SD卡启动好的板子linux上后使用flashcp烧写。
之后设置flash启动,将看到运行结果。这里面除了系统引导之前的fsbl和uboot能快一些之外(因此是从flash搬运到ocm或者DDR,而取代了从SD卡),运行linux的时间和结果没有任何的差别(因为LINUX 内核以及文件系统都在DDR内)。