s5pv210-Uboot启动流程

一、启动流程

1.s5pv210的启动过程

根据三星公司的《S5PV210_UM_REV1.1》手册可知,S5PV210 启动过程主要可 分为 3 个阶段

S5PV210 上电复位后将从 IROM 处执行已固化的启动代码 -------BL0
在 BL0 里初始化过程中对启动设备进行判断,并从启动设备拷贝 BL1(最大16KB ) 到 IRAM 处 , 即 刚 才 所 说 的 0xD0020000 开 始 的 地 址 , 其 中0xD0020000~0xD0020010 的 16 字节为 BL1 的校验信息和 BL1 尺寸,并对 BL1进行校验,校验通过转入 BL1 进行执行,BL1 继续初始化,并拷贝 BL2(最大80KB)到 IRAM 中并对其校验,通过后转入 BL2。
BL2 完成一些比较复杂的初始化,包括 DRAM 的初始化,完成后将 OS 代码拷贝到 DRAM 中,并跳到 OS 中执行并完成启动引导。


BL0 固化代码主要完成以下初始化:

关闭看门狗;
初始化 icache;
初始化栈;
初始化堆;
初始化块设备拷贝功能;
设置系统时钟;
拷贝 BL1 到 iRAM;
检查 BL1 的校验和,如果失败则第二启动模式(安全启动模式),校验成功则跳到 0xD0020000(IRAM)处执行。

其中 0xD0020000 ~ 0xD0020010 里的 16 字节头部信息是什么呢?这 16 字节信息用户是不能随便设置的.在《S5PV210_iROM_ApplicationNote_Preliminary_20091126》文档中规定

2.uboot中s5pv210的启动

2.1 uboot启动流程简介

BL0是出厂的时候就固化在IROM里的,所以我们的uboot就要实现BL1和BL2,BL1在uboot里叫做u-boot-spl.bin,BL2就是我们很熟悉的u-boot.bin.上面的三个阶段对应于uboot启动,他们的功能如下:

BL0:出厂的时候就固化在irom中一段代码,主要负责拷贝8kb的bl1到s5pv210的一个96kb大小内部sram(Internal SRAM)中运行。值得注意的是s5pv210的Internal SRAM支持的bl1的大小可以达到16kb,容量的扩增是为了适应bootloder变得越来复杂而做的。虽然如此,但目前我们制作出来的bl1的大小仍然可以保持在8kb以内,同样能满足需求。
BL1:u-boot的前8kb代码(s5pv210也支持16kb大小,原因上一点提过了),除了初始化系统时钟和一些基本的硬件外,主要负责完成代码的搬运工作(我设计成搬运bl1+bl2,而不仅仅是bl2),也就是将完整的u-boot代码(bl1+bl2)从nand flash或者mmcSD等的存储器中读取到内存中,然后跳转到内存中运行u-boot
BL2:完成全面的硬件初始化和加载OS到内存中,接着运行OS。上述几个阶段的流程描述在s5pv210_irom_application手册中有详细描述.
在实际的编译中会生成两个uboot.bin。拿webee210的uboot来说,最后在根目录下生成了uboot.bin和webee210-uboot.bin连个.bin文件。其中webee210-uboot.bin是通过/board/samsung/webee210/tools目录下的mkwebee210spl.bin对uboot.bin处理 生成的。主要是为其添加16k的头文件信息。


首先把启动部分的代码分为3部分,以start.S为主,另外还有lowlevel_init.S,mem_setup.S,ctr0.S。

lowlevel_init.S:主要是一部分硬件的初始化,尤其是系统时钟和DRAM的初始化。如果u-boot一旦被搬运到内存中运行,那么是必须要跳过时钟和DRAM的初始化的,因为这在搬运之前已经做过了。并且如果代码在内存中运行的时侯你却去初始化DRAM,那必然导致崩溃!
mem_setup.S:DRAM初始化代码和MMU相关代码放在这个文件中。
ctr0.S:u-boot自带的代码文件,存放汇编函数main。


2.2 启动过程

必须要明白的一点是,当代码从存储介质(nand flash,SD,norflash,onenand等)中搬运到了DRAM中后随即会跳转到内存中运行u-boot,接着会有一个重定位(relocate_code)的过程,relocate_code子函数在start.S中,而给relocate_code子函数传参数的是crt0.S中的main子函数。当判断到当前u-boot在内存的低地址处,那么relocate_code就会工作,把u-boot代码从低地址处再搬运到内存地址的顶端,然后跳转到新的位置去继续运行u-boot。而搬运的目标地址是在board_init_f()函数(此函数在/arch/arm/lib/board.c中)中计算出来的


2.2.1 start.S

#include <asm-offsets.h>
#include <config.h>
#include <version.h>
#include <common.h>
#include <configs/smart210.h>
#include <s5pc110.h>
.globl _start
_start: b	reset
	ldr	pc, _undefined_instruction  /*未定义指令异常,0x04*/  
	ldr	pc, _software_interrupt		/*软中断异常,0x08*/ 
	ldr	pc, _prefetch_abort         /*内存操作异常,0x0c*/ 
	ldr	pc, _data_abort				/*数据异常,0x10*/ 
	ldr	pc, _not_used				 /*未适用,0x14*/ 
	ldr	pc, _irq					/*慢速中断异常,0x1c*/
	ldr	pc, _fiq					/*快速中断异常,0x1c*/


#ifdef CONFIG_SPL_BUILD
_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
_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 */
#endif	/* CONFIG_SPL_BUILD */

.global _end_vect
_end_vect:

	.balignl 16,0xdeadbeef   //所以意思就是,接下来的代码,都要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
 *
 *************************************************************************/
 /*
此地址中是一个word类型的变量,变量名
是TEXT_BASE,此值见名知意,是text的base,即代码的基地址,
在include/configs/webee210.h
#define CONFIG_SYS_TEXT_BASE            0x23E00000*/

.globl _TEXT_BASE
_TEXT_BASE:
	.word	CONFIG_SYS_TEXT_BASE

#ifdef CONFIG_TEGRA2
/*
 * Tegra2 uses 2 separate CPUs - the AVP (ARM7TDMI) and the CPU (dual A9s).
 * U-Boot runs on the AVP first, setting things up for the CPU (PLLs,
 * muxes, clocks, clamps, etc.). Then the AVP halts, and expects the CPU
 * to pick up its reset vector, which points here.
 */
.globl _armboot_start
_armboot_start:
	.word _start        //*(_armboot_start) = _start
#endif

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

.global	_image_copy_end_ofs
_image_copy_end_ofs:
	.word 	__image_copy_end - _start

.globl _bss_end_ofs
_bss_end_ofs:
	.word __bss_end__ - _start

.globl _end_ofs
_end_ofs:
	.word _end - _start

#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
	.word	0x0badc0de

/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
	.word 0x0badc0de
#endif

/* IRQ stack memory (calculated at run-time) + 8 bytes */
.globl IRQ_STACK_START_IN
IRQ_STACK_START_IN:
	.word	0x0badc0de

reset函数里主要是设置了cpu的模式,然后就跳转到cpu_init_crit函数.

/*
 * the actual reset code
 */

reset:
    bl    save_boot_params    //其不做任何事情,直接返回
    /*
     * set the cpu to SVC32 mode  //设置CPU模式为SVC32
     */
    mrs    r0, cpsr
    bic    r0, r0, #0x1f
    orr    r0, r0, #0xd3
    msr    cpsr,r0


#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl    cpu_init_crit  //
#endif



/*************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************/
cpu_init_crit:
	/*
	 * Invalidate L1 I/D
	 */
	mov	r0, #0			@ set up for MCR
	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLBs
	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
	mcr	p15, 0, r0, c7, c5, 6	@ invalidate BP array
	mcr     p15, 0, r0, c7, c10, 4	@ DSB
	mcr     p15, 0, r0, c7, c5, 4	@ ISB

	/*
	 * disable MMU stuff and caches
	 */
	mrc	p15, 0, r0, c1, c0, 0
	bic	r0, r0, #0x00002000	@ clear bits 13 (--V-)
	bic	r0, r0, #0x00000007	@ clear bits 2:0 (-CAM)
	orr	r0, r0, #0x00000002	@ set bit 1 (--A-) Align
	or
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值