欢迎使用CSDN-markdown编辑器

http://blog.csdn.net/gameit/article/details/17464621

UBOOT之start.s分析

/**********设置处理器模式******************************/
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0

/*********************CPU和板级初始化*********************/

ifndef CONFIG_SKIP_LOWLEVEL_INIT

blcpu_init_crit //此函数就在start.s中

endif

cpu_init_crit:
/*
* I使无效TLB和指令cache
*/
movr0, #0
@ set up for MCR
mcrp15, 0, r0, c8, c7, 0
@ invalidate TLBs
mcrp15, 0, r0, c7, c5, 0
@ invalidate icache

/*
* disable MMU stuff and caches
*/
mrcp15, 0, r0, c1, c0, 0
bicr0, r0, #0x00002000
@ clear bits 13 (–V-)
bicr0, r0, #0x00000007
@ clear bits 2:0 (-CAM)
orrr0, r0, #0x00000002
@ set bit 1 (–A-) Align
orrr0, r0, #0x00000800
@ set bit 12 (Z—) BTB
mcrp15, 0, r0, c1, c0, 0

/*
* Jump to board specific initialization…
* The Mask ROM will have already initialized
* basic memory. Go here to bump up clock rate and handle
* wake up conditions.
*/

movip, lr @ persevere link reg across call
bllowlevel_init @板级初始化
movlr, ip @ restore link
movpc, lr
@ back to my caller

lowlevel_init做的主要工作就是关闭看门狗,关闭中断,初始化时钟,初始化DDR,初始化串口,如果定义了CONFIG_NAND,还会初始化nand控制器,初始化安全域控制器。此函数在lowlevel_init.S文件中,该文件目录为: board/厂家名/板名/,如 :board/samsung/smdkc100/lowlevel_init.S

主要由以下几个函数组成:
bl system_clock_init 初始化时钟
bl mem_ctrl_asm_init 初始化DDR
bl uart_asm_init 初始化串口
bl tzpc_init 初始化安全域

if defined(CONFIG_NAND)

bl nand_asm_init 简单初始化NAND

endif

对于以上函数不做详细说明,对照数据手册可自己更改。
以上函数全在lowlevel_init.S中,但注意 mem_ctrl_asm_init 可能不在 lowlevel_init.S中,而在mem_setup.S文件中,此文件与lowlevel_init.S在一个目录中。

/**************重定位****************/
relocate: @ relocate U-Boot to RAM
adr r0, _start @ r0 <- current position of code
ldr r1, _TEXT_BASE @ test if we run from flash or RAM
cmp r0, r1 @ don’t reloc during debug
beq stack_setup

ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 @ r2 <- size of armboot
add r2, r0, r2 @ r2 <- source end address

copy_loop: @ copy 32 bytes at a time
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 /* CONFIG_SKIP_RELOCATE_UBOOT */

其实这个段重定位代码是将片内IRAM中的代码搬移到DDR中。而我们通常是要将NAND中的数据搬移到DDR中,所以上面这段搬移代码可以忽略,自己写一个从NAND搬移数据到DDR的函数,放在此处。可以用C语言写,但注意一定要是位置无关码,因为此时我们的程序还运行在IRAM中,实际运行地址与链接地址不符。用C语言写位置无关码时,要全部使用局部变量。

ldr sp,=(0x22000000)
bl copy_uboot_to_ram
copy_uboot_to_ram函数便是一个从nand搬移代码到DDR的C语言函数,具体自己实现。

_TEXT_BASE:
.wordTEXT_BASE
_TEXT_BASE这个变量定义在start.S中,TEXT_BASE在链接脚本中定义

/*****分配空间****************/

stack_setup:
ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot
sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo

ifdef CONFIG_USE_IRQ

sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)

endif

sub sp, r0, #12 @ leave 3 words for abort-stack
and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d

以上这段代码主要为环境变量,动态内存malloc,全局结构体变量gd_t分配空间。以及设置了一个absort栈。分配空间后,uboot的空间分配如下:

CONFIG_SYS_MALLOC_LEN
CONFIG_SYS_GBL_DATA_SIZE
以上两个值在include/autoconf.mk中定义

/*****清除BSS段****************/
clear_bss:
ldr r0, _bss_start @ find start of bss segment
ldr r1, _bss_end @ stop here
mov r2, #0x00000000 @ clear value
clbss_l:
str r2, [r0] @ clear BSS location
cmp r0, r1 @ are we at the end yet
add r0, r0, #4 @ increment clear index pointer
bne clbss_l @ keep clearing till at end

以上这段代码主要的作用为清除BSS段

ldr pc, _start_armboot
跳到C函数,此函数在lib_arm/Board.c中定义,注:此时uboot才从片内ram跳转到了DDR2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值