ZYNQ 无DDR 启动

参考链接:
ZYNQ上无DDR加载应用
官方参考步骤

1 fsbl_bsp 相关修改

1.1 Translation_table.s

该文件位于E: …\fsbl_bsp\ps7_cortexa9_0\libsrc\standalone_v7_0\src 目录下

在文件第203-206 行内容屏蔽掉 并添加两段代码
原内容如下:

.rept	0x0020			/* 0xfc000000 - 0xfdffffff (Linear QSPI - XIP) */
.word	SECT + 0xc0a		/* S=b0 TEX=b000 AP=b11, Domain=b0, C=b1, B=b0 */
.set	SECT, SECT+0x100000
.endr

修改后文本内容如下:

#if 0
.rept	0x0020			/* 0xfc000000 - 0xfdffffff (Linear QSPI - XIP) */
.word	SECT + 0xc0a		/* S=b0 TEX=b000 AP=b11, Domain=b0, C=b1, B=b0 */
.set	SECT, SECT+0x100000
.endr
#endif


.rept	0x0007			/* 0xfc000000 - 0xfc6fffff (Linear QSPI - XIP) */
.word	SECT + 0xc0a		/* S=b0 TEX=b000 AP=b11, Domain=b0, C=b1, B=b1 */
.set	SECT, SECT+0x100000
.endr

.rept	0x0019			/* 0xfc700000 - 0xfdffffff (Linear QSPI - XIP) */
.word	SECT + 0x15de2	/* S=b0 TEX=b101 AP=b11, Domain=b0, C=b0, B=b0 */
.set	SECT, SECT+0x100000
.endr

增加的代码使用了QSPI内部的存储空间,用于执行FSBL,这里将QSPI配置为线性模式,分为2段XIP,7MB和25MB。这与后面提到的产生BIN文件时使用XIP模块相对应,同时0XFC000000这个地址将会用在fsbl的lscript.ld中。

1.2 xil_exception.c

向向量表条目添加了XVtable 属性。
该文件第93行
原内容为:

XExc_VectorTableEntry XExc_VectorTable[XIL_EXCEPTION_ID_LAST + 1] =

添加 XVtable 属性 修改后如下:

XExc_VectorTableEntry XExc_VectorTable[XIL_EXCEPTION_ID_LAST + 1] __attribute__ ((section("XVtable"))) =

以上为 fsbl_bsp 修改内容

2 fsbl 相关修改

2.1main.c

2.1.1 添加头文件

原文第138行 添加头文件

#include "xil_cache_l.h"
#include "xl2cc.h"
2.1.2 添加 preload_func 和 copy 函数及一些宏定义等 具体内容如下:

添加在 221 行 main() 函数前面即可 该函数将应用程序代码加载到缓存中并锁定它。
添加内容如下:

#ifdef DDRLESS_SYSTEM
#define XPAR_PS7_DDR_0_S_AXI_BASEADDR
#define WAY_SIZE 65536
#define	MAX_NUM_WAYS 8

/*****************************************************************************/
/**
*
* This function is used to preload and lock data in to L2 Cache.
*
*
* @param	None.
*
* @return
*		- XST_SUCCESS to indicate success
*		- XST_FAILURE.to indicate failure
*
* @note
*
****************************************************************************/
int preload_funct(unsigned int uiSrcAddress, unsigned int uiSize)
{
   
//	static unsigned int uiAlreadyProgrammed;
	unsigned int 		i=0;
//	unsigned int  		uiNumofWays=0;
//	unsigned int 		uiVariable=0;
//	unsigned int 		uiValue0=0;
//	unsigned int 		uiValue1=0;


	fsbl_printf(DEBUG_GENERAL,"\n\rInside  Preload Functions \n\r");
	// Disable FIQ and IRQ interrupt
	Xil_ExceptionDisableMask(XIL_EXCEPTION_ALL);
	/*
	 * UnLock Data and Instruction from way 1 to7 and unlock Data and instruction for Way 0.
	 * The PL310 has 8 sets of registers, one per possible CPU.
	 */
	for(i=0;i<8;i++)
	{
   
		Xil_Out32((XPS_L2CC_BASEADDR + (XPS_L2CC_CACHE_DLCKDWN_0_WAY_OFFSET + (i*8)) ), (0x00000000));
		Xil_Out32((XPS_L2CC_BASEADDR + (XPS_L2CC_CACHE_ILCKDWN_0_WAY_OFFSET + (i*8)) ), (0x00000000));

	}


	/* Flush the Caches */
	Xil_DCacheFlush();
	Xil_DCacheInvalidate();
	fsbl_printf(DEBUG_GENERAL,"\n\r Invalidate D cache \n\r");

	/*Preload instruction from section starts from 0x31000000 to Cache Way 0*/
	fsbl_printf(DEBUG_GENERAL,"Preload instructions uiSrcAddress = 0x%8x\n\r", uiSrcAddress);
	fsbl_printf(DEBUG_GENERAL,"Preload instructions       uiSize = 0x%8x\n\r", uiSize);

	{
   
	// Copy Applciation source adress to ro register
	 asm volatile ("mov r0,%0":: "r"(uiSrcAddress));
	 //Copy application size to r1 register
	 asm volatile ("mov r1,%0":: "r"(uiSize));
	 // Offset register i.e. r2
	 asm volatile  ("mov r2, #0");
	 // Label
	 asm ("preload_inst:");
	 // Load r4 register from the r0+r2 (Source address + offset)
	 // This step create an valid entry of the address (Source address + offset) in L2 cache
	 asm volatile ("ldr r4, [r0,r2]");
	 // Increment the offset by one cache line
	 asm volatile ("add r2,r2,#4");
	 // Compare the offset with the Application size.
	 asm volatile ("cmp r1, r2");
	 // If not equal jump to Label
	 asm volatile ("bge preload_inst");

	}

	// lock both Data and instruction caches from Way 1 to 7.
	// Lock Data and Instruction Caches for Way 0
	for(i=0;i<8;i++)
		{
   
			Xil_Out32((XPS_L2CC_BASEADDR + (XPS_L2CC_CACHE_DLCKDWN_0_WAY_OFFSET + (i*8)) ), 0xffff);
			Xil_Out32((XPS_L2CC_BASEADDR + (XPS_L2CC_CACHE_ILCKDWN_0_WAY_OFFSET + (i*8)) ), 0xffff);
		}
	fsbl_printf(DEBUG_GENERAL,"Lock both Data and instruction caches from Way 1 to 7\n\r");

	// Enable all the Interrupts
	Xil_ExceptionEnableMask(XIL_EXCEPTION_ALL);
//	uiAlreadyProgrammed=uiVariable;

	return - XST_SUCCESS;

}
#endif

extern char _image_start, _dataLMA, _dataVMA_start, _dataVMA_end, _vectorscopy, __vectors_start, __vectors_end;
extern char _dataXVtableLMA, _dataXVtableVMA_start,_dataXVtableVMA_end;


extern unsigned int _ncSTART_ADDR;

static void copy(char *src, char *dstStart, char *dstEnd) {
   
	/* ROM has data at end of text; copy it. */
	while (dstStart < dstEnd) {
   
		*dstStart++ = *src++;
	}
}
#define WRITE_VEC_BASE_ADDR(value) mtcp(XREG_CP15_VEC_BASE_ADDR,value)
#define READ_VEC_BASE_ADDR(value)  value = mfcp(XREG_CP15_VEC_BASE_ADDR)

以上添加完毕后会有一些报错 是因为 lscript.ld 文件还未修改 因此一些变量还未定义 所以不必关心!!!!

2.1.3 添加 data 拷贝

添加在mian() 函数中 变量定义后 原文本第 242 行 上面的修改后在第 355行
添加的文本如下:

copy(&_dataLMA,&_dataVMA_start,&_dataVMA_end);
copy(&_dataXVtableLMA,&_dataXVtableVMA_start,&_dataXVtableVMA_end);

以上添加完毕后会有一些报错 是因为 lscript.ld 文件还未修改 因此一些变量还未定义 所以不必关心!!!!

2.1.4 添加一些FSBL 数据地址的打印(可以不添加)

main() 函数中
上面的内容添加后在第 411行
添加的文本如下

/*
	 * Print the FSBL Banner
	 */
	fsbl_printf(DEBUG_GENERAL,"\n\rXilinx First Stage Boot Loader \n\r");
	fsbl_printf(DEBUG_GENERAL,"Release %d.%d	%s-%s\r\n",
			SDK_RELEASE_YEAR, SDK_RELEASE_QUARTER,
			__DATE__,__TIME__);
/*****************************以下为添加的内容********上面是原来就有的*********************/

	//fsbl_printf(DEBUG_GENERAL,"_image_start \t= 0x%8x\n\r", &_image_start);
		fsbl_printf(DEBUG_GENERAL,"_dataLMA \t= 0x%8x\n\r", &_dataLMA);
		fsbl_printf(DEBUG_GENERAL,"_dataVMA_start \t= 0x%8x\n\r", &_dataVMA_start);
		fsbl_printf(DEBUG_GENERAL,"_dataVMA_end \t= 0x%8x\n\r", &_dataVMA_end);
		//fsbl_printf(DEBUG_GENERAL,"_vectorscopy \t= 0x%8x\n\r", &_vectorscopy);
		//fsbl_printf(DEBUG_GENERAL,"__vectors_start \t= 0x%8x\n\r", &__vectors_start);
		//fsbl_printf(DEBUG_GENERAL,"__vectors_end \t= 0x%8x\n\r", &__vectors_end);
		fsbl_printf(DEBUG_GENERAL,"_dataXVtableLMA \t= 0x%8x\n\r", &_dataXVtableLMA);
		fsbl_printf(DEBUG_GENERAL,"_dataXVtableVMA_start \t= 0x%8x\n\r", &_dataXVtableVMA_start);
		fsbl_printf(DEBUG_GENERAL,"_dataXVtableVMA_end \t= 0x%8x\n\r", &_dataXVtableVMA_end);
2.1.5 对DDRInit 添加条件语句进行屏蔽

main() 函数中
上面的内容修改后 在第425 行
添加 DDRLESS_SYSTEM 条件

#ifndef DDRLESS_SYSTEM
#endif

添加后 内容如下:

#ifndef DDRLESS_SYSTEM
    /*
     * DDR Read/write test 
     */
	Status = DDRInitCheck();
	if (Status == XST_FAILURE) {
   
		fsbl_printf(DEBUG_GENERAL,"DDR_INIT_FAIL \r\n");
		/* Error Handling here */
		OutputStatus(DDR_INIT_FAIL);
		/*
		 * Calling FsblHookFallback instead of Fallback
		 * since, devcfg driver is not yet initialized
		 */
		FsblHookFallback();
	}

#endif
2.1.6 添加 flash 地址

main() 函数中:
上面内容添加后在 该文件第535 行
文本如下:

FlashReadBaseAddress = XPS_QSPI_LINEAR_BASEADDR;

添加后 内容如下:

#ifdef MMC_SUPPORT
	/*
	 * To support MMC boot
	 * QSPI boot mode detection ignored
	 */
	if (BootModeRegister == QSPI_MODE) {
   
		BootModeRegister = MMC_MODE;
	}
#endif

	if (BootModeRegister == QSPI_MODE) {
   
		fsbl_printf(DEBUG_GENERAL,"Boot mode is QSPI\n\r");
		InitQspi();
		MoveImage = QspiAccess;
		FlashReadBaseAddress = XPS_QSPI_LINEAR_BASEADDR;//添加语句!!!!!!!在这里
		fsbl_printf(DEBUG_INFO,"QSPI Init Done \r\n");
	} else
#endif
2.1.7 boot 镜像加载后添加 对 一级数据缓存操作

main() 函数中
上面内容添加后在该文件第 703 行
添加内容如下:

Xil_L1DCacheEnable();
Xil_L1ICacheEnable();
Xil_L1DCacheInvalidate();
Xil_L1ICacheInvalidate();

fsbl_printf(DEBUG_GENERAL,"-> FsblFallback\n\r");
//OutputStatus(NO_DDR);

添加后 文本如下:

/*
	 * Load boot image
	 */
	HandoffAddress = LoadBootImage();
	Xil_L1DCacheEnable();
		Xil_L1ICacheEnable();
		Xil_L1DCacheInvalidate();
		Xil_L1ICacheInvalidate();
2.1.8 main() 最后去掉 OutputStatus(NO_DDR);

main() 函数中:
以上内容修改后 在文件第 726 行 在该函数最后 return 之前
原内容如下:

#else
	OutputStatus(NO_DDR);
	FsblFallback();
#endif

	return Status;

修改后如下:

#else
	fsbl_printf(DEBUG_GENERAL,"-> FsblFallback\n\r");/* 还添加了一个debug 语句  可以不要 */
	//OutputStatus(NO_DDR);/* 这句话  !!!  屏蔽掉 */
	FsblFallback();
#endif

	return Status;
2.1.9 FsblHandoff() 函数 修改

FsblHandoff() 函数中!!!!!
以上内容修改后 在该文件第 912 行
原内容如下:

Status = FsblHookBeforeHandoff();

修改后如下 添加了一个传入的参数 该修改后 也会报错!!!! 因为原函数还未更改!!!

Status = FsblHookBeforeHandoff(FsblStartAddr);

以上 至此 main.c文件修改完成

2.2 fsbl.h

该文件 537 行
main() 函数中添加了 preload_funct() 函数 该函数在其它文件中有调用 所以 添加一下 函数声明
添加内容如下:

int preload_funct(unsigned int uiSrcAddress, unsigned int uiSize);/* __attribute__ ((section ("ncmemory")));*/

2.3 fsbl_handoff.S

因为程序不在DDR中执行,需要修改FsblHandoffExit段
源文件第85 行 140 行 198行 该文件中有三处对 FsblHandoffExit段的定义 不知道具体用哪一个 就全部都修改了吧
修改后 文本如下:

FsblHandoffExit:
#ifdef DDRLESS_SYSTEM
		mov	 lr, r0	/* move the destination address into link register */
		bx		lr	/* force the switch, destination should have been in r0 */
#else
		mov	 lr, r0	/* move the destination address into link register */

		mcr	 15,0,r0,cr7,cr5,0		/* Invalidate Instruction cache */
		mcr	 15,0,r0,cr7,cr5,6		/* Invalidate branch predictor array */

		dsb
		isb					/* make sure it completes */

	ldr	r4, =0
		mcr	 
  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值