1.4.7. cal armboot size from CopyCode2Ram

#if 1
	1bl  CopyCode2Ram		/* r0: source, r1: dest, r2: size */
#else
	add	r2, r0, r2		/* r2 <- source end address         */

copy_loop:
	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
	cmp	r0, r2			/* until source end addreee [r2]    */
	ble	copy_loop
#endif
#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
        

1

此处,代码很简单,只是注释掉了原先的那些代码,而单纯的只是去调用CopyCode2Ram这个函数。

CopyCode2Ram函数,前面也提到过了,是在:

u-boot-1.1.6_20100601\opt\EmbedSky\u-boot-1.1.6\board\EmbedSky\boot_init.c

中:

int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size)
{
	unsigned int *pdwDest;
	unsigned int *pdwSrc;
	int i;

	if (bBootFrmNORFlash())
	{
		pdwDest = (unsigned int *)buf;
		pdwSrc  = (unsigned int *)start_addr;
		/* 从 NOR Flash启动 */
		for (i = 0; i < size / 4; i++)
		{
			pdwDest[i] = pdwSrc[i];
		}
		return 0;
	}
	else
	{
		/* 初始化NAND Flash */
		nand_init_ll();

		/* 从 NAND Flash启动 */
		if (NF_ReadID() == 0x76 )
			nand_read_ll(buf, start_addr, (size + NAND_BLOCK_MASK)&~(NAND_BLOCK_MASK));
		else
			nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));
		return 0;
	}
}
                

可以看到,其有三个参数,start_addr,*buf和size,这三个参数,分别正好对应着我们刚才所总结的r0,r1和r2.

这些寄存器和参数的对应关系,也是APSC中定义的:

实际参数

APCS 没有定义记录、数组、和类似的格局。这样语言可以自由的定义如何进行这些活动。但是,如果你自己的实现实际上不符合 APCS 的精神,那么将不允许来自你的编译器的代码与来自其他编译器的代码连接在一起。典型的,使用 C 语言的惯例。

  • 前4个整数实参(或者更少!)被装载到 a1 - a4
  • 前 4 个浮点实参(或者更少!)被装载到 f0 - f3
  • 其他任何实参(如果有的话)存储在内存中,用进入函数时紧接在 sp 的值上面的字来指向。换句话说,其余的参数被压入栈顶。所以要想简单。最好定义接受 4 个或更少的参数的函数

上面说的a1-a4,就是寄存器r0-r3。

而CopyCode2Ram函数的逻辑也很清晰,就是先去判断是从Nor Flash启动还是从Nand Flash启动,然后决定从哪里拷贝所需要的代码到对应的目标地址中。