uboot移植---start.s分析

具体见注释

#include <config.h>
#include <version.h>
#ifdef CONFIG_ENABLE_MMU
#include <asm/proc/domain.h>
#endif
#include <asm/arch/s3c6410.h>

#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
#define CONFIG_SYS_PHY_UBOOT_BASE	CONFIG_SYS_UBOOT_BASE
#endif

/*
 *************************************************************************
 *
 * Jump vector table as in table 3.1 in [1]
 *
 *************************************************************************
 */

.globl _start
_start: b	reset
#ifndef CONFIG_NAND_SPL
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq

_undefined_instruction:
	.word undefined_instruction
_software_interrupt:
	.word software_interrupt
_prefetch_abort:
	.word prefetch_abort
_data_abort:
	.word data_abort
_not_used:
	.word not_used
_irq:
	.word irq
_fiq:
	.word fiq
_pad:
	.word 0x12345678 /* now 16*4=64 */
#else
	. = _start + 64
#endif

.global _end_vect
_end_vect:
	.balignl 16,0xdeadbeef
/*
 *************************************************************************
 *
 * Startup Code (reset vector)
 *
 * do important init only if we don't start from memory!
 * setup Memory and board specific bits prior to relocation.
 * relocate armboot to ram
 * setup stack
 *
 *************************************************************************
 */

_TEXT_BASE:
	.word	TEXT_BASE

/*
 * Below variable is very important because we use MMU in U-Boot.
 * Without it, we cannot run code correctly before MMU is ON.
 * by scsuh.
 */
_TEXT_PHY_BASE:
	.word	CONFIG_SYS_PHY_UBOOT_BASE

.globl _armboot_start
_armboot_start:
	.word _start

/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start
_bss_start:
	.word __bss_start

.globl _bss_end
_bss_end:
	.word _end

/*
 * the actual reset code
 */
/* 从reset开始看,前面就不分析了 */
reset:
	/*
	 * 设置SVC超级用户模式,就是这么规定,可参考 
	 *《ARM ArchitectureReference Manual》 的 Program status registers 一节
	 */
	mrs	r0, cpsr
	bic	r0, r0, #0x3f
	orr	r0, r0, #0xd3
	msr	cpsr, r0

/*
 *************************************************************************
 *
 * CPU_init_critical registers
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */
	/*
	 * we do sys-critical inits only at reboot,
	 * not when booting from ram!
	 */
cpu_init_crit:
	/*
	 * When booting from NAND - it has definitely been a reset, so, no need
	 * to flush caches and disable the MMU
	 */
#ifndef CONFIG_NAND_SPL
	/*
	 * flush v4 I/D caches  清除数据缓存和指令缓存
	 */
	mov	r0, #0
	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */

	/*
	 * disable MMU stuff and caches  
	 * 关闭MMU和数据缓存,开启指令缓存
	 * 设置参照arm1176jzfs文档3.2.7节  
	 */
	mrc	p15, 0, r0, c1, c0, 0																	
	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
	/*
	 * 下面这行原先是在第193行,关闭了MMU,如果不注释掉的话当执行到 MOV PC,R2后就应该是
	 * 转跳到了内存中间运行,而此时我们的DDR和其他外设没初始化,而且代码也没有重定位
	 */
	mcr	p15, 0, r0, c1, c0, 0								
	/* Prepare to disable the MMU */
#if 0
	adr	r1, mmu_disable_phys
	/* We presume we're within the first 1024 bytes */
	and	r1, r1, #0x3fc
	ldr	r2, _TEXT_PHY_BASE
	ldr	r3, =0xfff00000
	and	r2, r2, r3
	orr	r2, r2, r1
	b	mmu_disable

	.align 5
	/* Run in a single cache-line */
mmu_disable:
	mcr	p15, 0, r0, c1, c0, 0
	nop
	nop
	mov	pc, r2
#endif
#endif
/* 设置外设基地址 */
mmu_disable_phys:
	/* Peri port setup */
	ldr	r0, =0x70000000
	orr	r0, r0, #0x13
	mcr	p15,0,r0,c15,c2,4       @ 256M (0x70000000 - 0x7fffffff)

	/*
	 * 跳到 lowlevel_init 执行底层初始化 ,
	 * 至于怎么初始化先不管,暂且认为他初始化好了DDR,UART.....等等外设
	 */
	bl	lowlevel_init			/* go setup pll,mux,memory */
	
/*  CONFIG_ENABLE_MMU没有定义,下面这段代码不用看 */
after_copy:
#if 0
#ifdef CONFIG_ENABLE_MMU
enable_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, =CONFIG_SYS_PHY_UBOOT_BASE
	ldr	r2, =0xfff00000
	bic	r0, r0, r2
	orr	r1, r0, r1
	mcr	p15, 0, r1, c2, c0, 0

	/* Enable the MMU */
	mrc	p15, 0, r0, c1, c0, 0
	orr	r0, r0, #1		/* Set CR_M to enable MMU */

	/* Prepare to enable the MMU */
	adr	r1, skip_hw_init
	and	r1, r1, #0x3fc
	ldr	r2, _TEXT_BASE
	ldr	r3, =0xfff00000
	and	r2, r2, r3
	orr	r2, r2, r1
	b	mmu_enable

	.align 5
	/* Run in a single cache-line */
mmu_enable:

	mcr	p15, 0, r0, c1, c0, 0
	nop
	nop
	mov	pc, r2
#endif
#endif
/*  下一步是设置栈地址,其内存分布图如下:
*
*		+---------------------------------------+  	<-----  r0 = CONFIG_SYS_UBOOT_BASE = 0x57e00000 
*		|					|
*		|	CONFIG_SYS_MALLOC_LEN		|
*		|					|
*		+---------------------------------------+	<-----  r0 = r0 - CONFIG_SYS_MALLOC_LEN
*		|					|
*		|	CONFIG_SYS_GBL_DATA_SIZE	|
*		|					|
*		+---------------------------------------+	<-----  r0 = r0 - CONFIG_SYS_GBL_DATA_SIZE
*		|					|
*		|		12 BYTE			|
*		+---------------------------------------+	<-----  sp = r0 - 12	
*/
skip_hw_init:
	/* Set up the stack						    */
stack_setup:
	ldr	r0, =CONFIG_SYS_UBOOT_BASE	/* base of copy in DRAM	    */
	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN	/* malloc area                      */
	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */
	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
	
/* 清除BSS段 */
clear_bss:
	ldr	r0, _bss_start		/* find start of bss segment        */
	ldr	r1, _bss_end		/* stop here                        */
	mov 	r2, #0			/* clear                            */
clbss_l:
	str	r2, [r0]		/* clear loop...                    */
	add	r0, r0, #4
	cmp	r0, r1
	ble	clbss_l

#ifndef CONFIG_NAND_SPL
/* 转跳到start_armboot去执行,正常来说跳转过去后是不会回来了的,所以后面的代码不用看了 */
	ldr	pc, _start_armboot

_start_armboot:
	.word start_armboot
#else
	b	nand_boot
/*	.word nand_boot*/
#endif


<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">我们发现start.s并未对代码进行重定位,而且lowlevel_init和start_armboot也没有对代码重定位,所以代码重定位的工作就需要我们自己做了</span>

下篇准备分许lowlevel_init,那重定位就下下篇说吧

实际上 配置CONFIG_NAND_SPL应该是会进行代码重定位,不过还没时间去试试

等有时间试试看




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值