u-boot之start.S分析(三)

重新设置栈

/* get ready to call C functions */
ldr	sp, _TEXT_PHY_BASE	/* setup temp stack pointer */
sub	sp, sp, #12
mov	fp, #0			/* no previous frame, so fp=0 */
  • u-boot之start.S分析(一)的最后一部分我们已经设置了栈地址,但是只有不到8K的大小,这显然是不够的。由于当时我们并没有初始化DDR,所以只能将栈设置到不需要初始化的内部IRAM中。现在我们已经将DDR初始化好了,因此需要重新将栈移动到DDR中,这样可以避免栈溢出的风险
  • _TEXT_PHY_BASE是指uboot代码段物理地址的基地址,最后找到了它的出处(如下)
  1. start.S的开始部分有CFG_PHY_UBOOT_BASE的宏定义,但是由于我们定义了CONFIG_ENABLE_MMU,因此这一关于CFG_PHY_UBOOT_BASE宏定义的语句不起作用。
#ifndef CONFIG_ENABLE_MMU
#ifndef CFG_PHY_UBOOT_BASE
#define CFG_PHY_UBOOT_BASE	CFG_UBOOT_BASE
#endif
#endif
  1. 最后在头文件中找到了定义,因此最后的值为0x33e00000,在我们的DRAM0内部
#define MEMORY_BASE_ADDRESS	0x30000000
#define CFG_PHY_UBOOT_BASE	MEMORY_BASE_ADDRESS + 0x3e00000

在这里插入图片描述

  • 这里将栈的地址定位到0x33e00000,由于MMU的关系,该地址就是TEXT_BASE定义的代码段地址0xc3e00000(u-boot之内存地址映射)。由于ARM是满减栈,所以栈是从高地址往下栈的,因此不会对代码段产生影响。

判断是否需要重定位

/* when we already run in ram, we don't need to relocate U-Boot.
 * and actually, memory controller must be configured before U-Boot
 * is running in ram.
 */
ldr	r0, =0xff000fff
bic	r1, pc, r0		/* r0 <- current base addr of code */
ldr	r2, _TEXT_BASE		/* r1 <- original base addr in ram */
bic	r2, r2, r0		/* r0 <- current base addr of code */
cmp     r1, r2                  /* compare r0, r1                  */
beq     after_copy		/* r0 == r1 then skip flash copy   */
  • 判断运行地址是在SRAM还是DDR中,以进行uboot的重定位。
  • 冷启动时uboot的前一部分开机自动从SD卡加载到SRAM中运行,uboot的第二部分(其实是整个uboot)依然在SD卡中。
  • 这里要做的就是将第二部分加载到DDR的链接地址处(0x33e00000)。

SD卡设备判断

#if defined(CONFIG_EVT1)
	/* If BL1 was copied from SD/MMC CH2 */
	ldr	r0, =0xD0037488
	ldr	r1, [r0]
	ldr	r2, =0xEB200000
	cmp	r1, r2
	beq     mmcsd_boot
#endif
  • 0xD0037488地址来源于《S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf》文件,这个地址中的值指示了从哪个SD卡地址启动的。

在这里插入图片描述

  • SDMMC0,1,2的设备起始地址分别为0xEB00_0000,0xEB10_0000,0xEB20_0000
  • 因此cmp r1, r2是在检测是否从外部SD卡启动
  • 代码最终进入mmcsd_boot执行重定位

重定位

void movi_bl2_copy(void)
{
	ulong ch;
#if defined(CONFIG_EVT1)
	ch = *(volatile u32 *)(0xD0037488);
	copy_sd_mmc_to_mem copy_bl2 =
	    (copy_sd_mmc_to_mem) (*(u32 *) (0xD0037F98));

	#if defined(CONFIG_SECURE_BOOT)
	ulong rv;
	#endif
#else
	ch = *(volatile u32 *)(0xD003A508);
	copy_sd_mmc_to_mem copy_bl2 =
	    (copy_sd_mmc_to_mem) (*(u32 *) (0xD003E008));
#endif
	u32 ret;
	if (ch == 0xEB000000) {
		ret = copy_bl2(0, MOVI_BL2_POS, MOVI_BL2_BLKCNT,
			CFG_PHY_UBOOT_BASE, 0);

#if defined(CONFIG_SECURE_BOOT)
		/* do security check */
		rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
				      (unsigned char *)CFG_PHY_UBOOT_BASE, (1024*512-128),
			              (unsigned char *)(CFG_PHY_UBOOT_BASE+(1024*512-128)), 128 );
		if (rv != 0){
				while(1);
			}
#endif
	}
	else if (ch == 0xEB200000) {
		ret = copy_bl2(2, MOVI_BL2_POS, MOVI_BL2_BLKCNT,
			CFG_PHY_UBOOT_BASE, 0);
		
#if defined(CONFIG_SECURE_BOOT)
		/* do security check */
		rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR,
				      (unsigned char *)CFG_PHY_UBOOT_BASE, (1024*512-128),
			              (unsigned char *)(CFG_PHY_UBOOT_BASE+(1024*512-128)), 128 );
		if (rv != 0) {
			while(1);
		}
#endif
	}
	else
		return;

	if (ret == 0)
		while (1)
			;
	else
		return;
}
  • 代码最终通过执行一个长跳转语句bl movi_bl2_copy执行C语言程序,经过搜索,此函数位于cpu/s5pc11x/movi.c文件中

内存管理单元(MMU)

/* enable domain access */
	ldr	r5, =0x0000ffff
	mcr	p15, 0, r5, c3, c0, 0		@load domain access register

	/* Set the TTB register */
	ldr	r0, _mmu_table_base
	ldr	r1, =CFG_PHY_UBOOT_BASE
	ldr	r2, =0xfff00000
	bic	r0, r0, r2
	orr	r1, r0, r1
	mcr	p15, 0, r1, c2, c0, 0
	/* enable domain access */
	ldr	r5, =0x0000ffff
	mcr	p15, 0, r5, c3, c0, 0		@load domain access register

	/* Set the TTB register */
	ldr	r0, _mmu_table_base
	ldr	r1, =CFG_PHY_UBOOT_BASE
	ldr	r2, =0xfff00000
	bic	r0, r0, r2
	orr	r1, r0, r1
	mcr	p15, 0, r1, c2, c0, 0

	/* Enable the MMU */
mmu_on:
	mrc	p15, 0, r0, c1, c0, 0
	orr	r0, r0, #1
	mcr	p15, 0, r0, c1, c0, 0
  • MMU单元在CP15协处理器中进行控制,因此我们要对cp15协处理器的寄存器进行编程
  • 要设置地址转换表基地址(translation table base,TTB)并使能MMU
  • _mmu_table_base就是转换表基地址,这个最后指示的是mmu_table,这在lowlevel_init.S
  • 内存地址映射在u-boot之内存地址映射详细分析
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贱贱的剑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值