uboot(三)—— crt0_64.S(relocate_code)

目录

一、crt0_64.S的uboot重定位代码

二、relocate_code


一、crt0_64.S的uboot重定位代码

作用:把uboot搬运到高端内存区,为Kernel的加载提供内存,避免内存践踏。

/*
 * Set up intermediate environment (new sp and gd) and call
 * relocate_code(addr_moni). Trick here is that we'll return
 * 'here' but relocated.
 */
	ldr	x0, [x18, #GD_START_ADDR_SP]	/* x0 <- gd->start_addr_sp */
	bic	sp, x0, #0xf	/* 16-byte alignment for ABI compliance */ //bic位清除
	ldr	x18, [x18, #GD_NEW_GD]		/* x18 <- gd->new_gd */
    //把gd放在x18寄存器

	/* Skip relocation in case gd->gd_flags & GD_FLG_SKIP_RELOC */
	ldr	x0, [x18, #GD_FLAGS]		/* x0 <- gd->flags */
	tbnz	x0, 11, relocation_return	/* GD_FLG_SKIP_RELOC is bit 11 *///tbnz	测试位不为0,则跳转。
	adr	lr, relocation_return

	/* Add in link-vs-relocation offset */
	ldr	x9, [x18, #GD_RELOC_OFF]	/* x9 <- gd->reloc_off */
	add	lr, lr, x9	/* new return address after relocation */
	ldr	x0, [x18, #GD_RELOCADDR]	/* x0 <- gd->relocaddr */
    //计算返回地址在新的uboot空间中的地址,并把uboot的新的地址空间放到r0寄存器中
    //r0作为relocate_code的参数传递进去

	b	relocate_code

relocation_return:

/*
 * Set up final (full) environment
 */
	bl	c_runtime_cpu_setup		/* still call old routine */

二、relocate_code

调用relocate_code实现重定位。
位置u-boot-2022.01\arch\arm\lib\crt0_64.S

/*
 * void relocate_code(addr_moni)
 *
 * This function relocates the monitor code.
 * x0 holds the destination address.
 */
ENTRY(relocate_code)
	stp	x29, x30, [sp, #-32]!	/* create a stack frame */
	mov	x29, sp
	str	x0, [sp, #16]
	/*
	 * Copy u-boot from flash to RAM 
	 */
	adrp	x1, __image_copy_start		/* x1 <- address bits [31:12] */
	add	x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
	subs	x9, x0, x1			/* x9 <- Run to copy offset */
	b.eq	relocate_done			/* skip relocation */
	/*
	 * Don't ldr x1, __image_copy_start here, since if the code is already
	 * running at an address other than it was linked to, that instruction
	 * will load the relocated value of __image_copy_start. To
	 * correctly apply relocations, we need to know the linked value.
	 *
	 * Linked &__image_copy_start, which we know was at
	 * CONFIG_SYS_TEXT_BASE, which is stored in _TEXT_BASE, as a non-
	 * relocated value, since it isn't a symbol reference.
	 */
	ldr	x1, _TEXT_BASE		/* x1 <- Linked &__image_copy_start */
	subs	x9, x0, x1		/* x9 <- Link to copy offset */

	adrp	x1, __image_copy_start		/* x1 <- address bits [31:12] */
	add	x1, x1, :lo12:__image_copy_start/* x1 <- address bits [11:00] */
	adrp	x2, __image_copy_end		/* x2 <- address bits [31:12] */
	add	x2, x2, :lo12:__image_copy_end	/* x2 <- address bits [11:00] */

//完成代码拷贝工作,
copy_loop: 
	ldp	x10, x11, [x1], #16	/* copy from source address [x1] */
	stp	x10, x11, [x0], #16	/* copy to   target address [x0] */
	cmp	x1, x2			/* until source end address [x2] */
	b.lo	copy_loop
	str	x0, [sp, #24]

	/*
	 * Fix .rela.dyn relocations(用于动态重定位)
	 */
	adrp	x2, __rel_dyn_start		/* x2 <- address bits [31:12] */
	add	x2, x2, :lo12:__rel_dyn_start	/* x2 <- address bits [11:00] */
	adrp	x3, __rel_dyn_end		/* x3 <- address bits [31:12] */
	add	x3, x3, :lo12:__rel_dyn_end	/* x3 <- address bits [11:00] */
fixloop:
	ldp	x0, x1, [x2], #16	/* (x0,x1) <- (SRC location, fixup) */
	ldr	x4, [x2], #8		/* x4 <- addend */
	and	x1, x1, #0xffffffff
	cmp	x1, #R_AARCH64_RELATIVE
	bne	fixnext

	/* relative fix: store addend plus offset at dest location */
	add	x0, x0, x9
	add	x4, x4, x9
	str	x4, [x0]
fixnext:
	cmp	x2, x3
	b.lo	fixloop

relocate_done:
	switch_el x1, 3f, 2f, 1f
	bl	hang
3:	mrs	x0, sctlr_el3
	b	0f
2:	mrs	x0, sctlr_el2
	b	0f
1:	mrs	x0, sctlr_el1
0:	tbz	w0, #2, 5f	/* skip flushing cache if disabled */
	tbz	w0, #12, 4f	/* skip invalidating i-cache if disabled */
	ic	iallu		/* i-cache invalidate all */
	isb	sy
4:	ldp	x0, x1, [sp, #16]
	bl	__asm_flush_dcache_range
	bl     __asm_flush_l3_dcache
5:	ldp	x29, x30, [sp],#32
	ret
ENDPROC(relocate_code)

参考博文

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dz小伟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值