二阶段的目标是将fsbl在qspi中xip模式运行,helloworld应用程序在L2 cache中正常运行。
首先新建工程完成无ddr使用ocm运行加载,保证fsbl代码正常运行。
然后再针对XIP进行修改,与L2 cache lock运行程序。相比第一阶段增加的内容使用蓝色标示。
1、增加预编译宏
增加4个宏,DDRLESS_SYSTEM,QSPI_XIP,FSBL_DEBUG_INFO,APP_XIP_L2
2、修改translation_table.S文件
文件位于bsp下的路径
\FSBL_XIP_bsp\ps7_cortexa9_0\libsrc\standalone_v5_0\src\translation_table.S
3、修改FSBL_XIP的lscript.ld文件
通过查看已经生成.elf文件,可以查看目前sections分配,对于.elf文件中不存在的sections在lscript.ld文件中可以不分配,并且那些section可以删除。
根据生成的.elf文件分析各个段的属性,是否只读,是否需要load。
而对于.text等具有READONLY属性的段,则可以直接放到QSPI Flash中运行,即XIP模式。
直接分配到OCM中的段,包括stack与heap段,在段后已经标明(NOLOAD)说明。
对.data段进行特殊处理,需要load,即需要从QSPI Flash中搬移到ocm中,如下
.data : {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > ps7_ram_0_S_AXI_BASEADDR AT > QSPI_FLASH
_dataLMA = LOADADDR(.data); /* 记录地址 */
需要将.rsa_ac设置为NOLOAD,并且增加.sbss段。也可以与demo程序一样,将.rsa_ac段删除。我选择了保留是因为在.elf中有这个段,尽量与.elf保持一致。
如果保留.rsa_ac而没有设置为NOLOAD属性,出现存储器耗尽(memory exhausted)的错误提示如下。
增加.XVtable段,设置为NOLOAD属性
在没有XVTable时elf文件的完整SYMBOL TABLE
增加XVtable后的elf文件分析,XVtable存放的为中断向量表信息(interrupt vector table)。
在link阶段的提示如下:
Building target: FSBL_XIP.elf
Invoking: ARM gcc linker
arm-xilinx-eabi-gcc -L"E:\Test\MicroZed\ZYNQ_XIP\ZYNQ_XIP.sdk\FSBL_XIP\src" -Wl,-T -Wl,../src/lscript.ld -L../../FSBL_XIP_bsp/ps7_cortexa9_0/lib -o "FSBL_XIP.elf" ./src/fsbl_handoff.o ./src/fsbl_hooks.o ./src/image_mover.o ./src/main.o ./src/md5.o ./src/nand.o ./src/nor.o ./src/pcap.o ./src/ps7_init.o ./src/qspi.o ./src/rsa.o ./src/sd.o -lrsa -Wl,--start-group,-lxil,-lgcc,-lc,--end-group -Wl,--start-group,-lxilffs,-lxil,-lgcc,-lc,--end-group -Wl,--start-group,-lrsa,-lxil,-lgcc,-lc,--end-group
d:/xilinx/sdk/2015.1/gnu/arm/nt/bin/../lib/gcc/arm-xilinx-eabi/4.9.1/../../../../arm-xilinx-eabi/bin/ld.exe: FSBL_XIP.elf: section `.data' can't be allocated in segment 0
LOAD: .text .handoff .init .fini .rodata .data .eh_frame .mmu_tbl .init_array .fini_array .rsa_ac
Finished building target: FSBL_XIP.elf
与vivado2016.2版中的提示一样,所以不用理会。
3、修改main.c文件
将viavdo2016.2中的preload_funct()与copy()函数内容拷贝到main.c文件中,并且增加包含xl2cc.h头文件。
增加QSPI_XIP宏,并且将LinearBootDeviceFlagc初值赋值为1。
4、修改fsbl_handoff.s文件
在加载完成后跳转,由于没有ddr所以不需要操作cache,修改后如下
5、修改image_mover.c文件
注释掉对FSBL所属的判定;
注释掉对load address check判定,因为它只判定ddr的地址空间为有效的,其它的均无效;
将代码从boot device搬到内部(PL 逻辑代码)前开启L2 cache
PartitionMove()函数修改
增加对arm加载的L2锁存处理,并preload_funct()函数的一个参数仅为SourceAddr。
6、修改qspi.c文件
主要是InitQspi(void)中关于qspi初始化部分注释掉,因为运行fsbl xip模式,fsbl的代码已经在qspi中运行了,所以此时再初始化qspi将造成死机。
在下图中,QSPI_XIP所在的行开始,到函数返回值之前的代码都注释掉。
7、对helloworld工程的修改
这个工程不能与BSP关联,需要将bsp中相关的文件拷贝出来进行编译。可以将demo程序中的standalone与uartps文件夹(由于本例程中没有使用中断,所以不需要scugic文件夹中的内容)拷贝到helloworld工程下,然后修改startup.s与lscript.ld文件,和demo保持一致就可以了。
对helloworld工程编译选项的修改,去掉包含关于bsp的头文件与lib文件信息,去掉build option信息。
8、编辑bif文件
需要和demo中的bif文件一样,设置每个文件的偏移地址。
最后生成bin文件时,必须使用批处理生成,参见zynq soc无外部存储器在QSPI Flash下XIP模式加载运行的中说明。此处又是一个神坑,vivado2015.1的bootgen生成的.bin文件就是不能加载,而使用vivado2016.2版本与vivado2014.2版本均可以正常加载。
发表于2018-04-26 at 10:11 地板
你好,请问能把lscript.ld发我吗?我按照您说的去改ld文件,不会出现那个错误,按照官方的例子修改才会出现那个错误
发表于2018-05-06 at 17:46
时间长了,我做的例子也找不到了。
发表于2018-06-08 at 22:00 板凳
如果在程序中想操作读写qflash,应该怎么操作呢
发表于2018-06-10 at 15:38
根据Flash的cmd指令操作,不要将存放程序的地址擦除,否则下次上电就不能加载了
发表于2019-06-19 at 16:54 沙发
博主,项目上急需这个方法。您的例程能让我参考一下嘛?感激不尽,也可以利用项目的钱买这个例程,谢谢啦