![](https://images.cnblogs.com/cnblogs_com/zhangsufeng/1.jpg)
![](https://images.cnblogs.com/cnblogs_com/zhangsufeng/2.jpg)
![](https://images.cnblogs.com/cnblogs_com/zhangsufeng/3.jpg)
![](https://images.cnblogs.com/cnblogs_com/zhangsufeng/4.jpg)
_start: b start_code ;跳转到start_code处执行
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
.balignl 16,0xdeadbeef ;将上面代码16字节对齐,参考http://zqwt.012.blog.163.com/blog/static/12044684201031102956976/
/*
*************************************************************************
*
* Startup Code (called from the ARM reset exception vector)
*
* do important init only if we don't start from memory!
* relocate armboot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
.globl _TEXT_BASE
_TEXT_BASE:
.word CONFIG_SYS_TEXT_BASE
/*
* These are defined in the board-specific linker script.
* Subtracting _start from them lets the linker put their
* relative position in the executable instead of leaving
* them null.
*/
//定义于board/smdk2410/u-boot.lds
.globl _bss_start_ofs
_bss_start_ofs:
.word __bss_start - _start
.globl _bss_end_ofs
_bss_end_ofs:
.word __bss_end__ - _start
.globl _end_ofs
_end_ofs:
.word _end - _start
切换到此启动:
start_code:
/*
* 设置cpu保护模式启动
*/
mrs r0, cpsr
bic r0, r0, #0x1f ;0x1f= 11111 ,将cpsr的m[4:0]清0
orr r0, r0, #0xd3 ;将cpsr的m[4:0]设置为0xd3(10011),即SVC模式
msr cpsr, r0
#ifdef CONFIG_S3C24X0
通过datasheet查下面的地址
# define pWTCON 0x53000000 /*watchdog timer control register */
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
# define CLKDIVN 0x4C000014 /* clock divisor register */
/* 关闭看门狗 */
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0] 将pWTCON地址存0,0为关看门狗
/*
* 关所有的中断,1为使中断失效
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
/* 设置 FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
/*通过设置PLLCON 和CLKDIVN寄存器来实现超频*/
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif /* CONFIG_S3C24X0 */
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
在此先插入该label的代码
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
/*
* 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
*/
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
mcr p15, 0, r0, c1, c0, 0
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
mov ip, lr
bl lowlevel_init ;转到board\samsung\smdk2410\lowlevel_init.S执行
mov lr, ip
mov pc, lr //返回调用处
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
再插代码:
_TEXT_BASE:
.word CONFIG_SYS_TEXT_BASE
定义在:board\samsung\smdk2400\config.mk中CONFIG_SYS_TEXT_BASE = 0x0CF80000
.globl lowlevel_init
lowlevel_init:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
见:http://weimenlove.blog.163.com/blog/static/1777547320110212134343/
;3. 设置存储相关寄存器
;这是设置SDRAM,flash ROM 存储器连接和工作时序的程序,片选定义的程序,SMRDATA map在下面的程序中定义
ldr r0, =SMRDATA ;存放了13个DCD数据,不附代码了
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =BWSCON /*存储管理器*/
add r2, r0, #13*4 ;End address of SMRDATA
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
;设置存储器控制寄存器从CONFIG_SYS_TEXT_BASE依次填入之前存储到13个DCD数据,这个是典型到汇编循环
/* everything is fine now */
mov pc, lr //返回调用处
参考:http://blog.163.com/jiangh_1982/blog/static/12195052010615511574/
继续start.S中执行
在此设置栈内存,(以前版本是在stack_setup这,将sp指向一块定义好的内存中)
/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)//这个宏定义在include\configs\smdk2410.h ?
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r0,=0x00000000 //调用函数前,将参数a1(见APCS)置为0
bl board_init_f //进入C初始化
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
*/
copy_loop:
ldmia r0!, {r9-r10} /* copy from source address [r0] */
stmia r1!, {r9-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
blo copy_loop
#ifndef CONFIG_PRELOADER
/*
* fix .rel.dyn relocations
*/
ldr r0, _TEXT_BASE /* r0 <- Text base */
sub r9, r6, r0 /* r9 <- relocation offset */
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
add r10, r10, r0 /* r10 <- sym table in FLASH */
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
add r0, r0, r9 /* r0 <- location to fix up in RAM */
ldr r1, [r2, #4]
and r7, r1, #0xff
cmp r7, #23 /* relative fixup? */
beq fixrel
cmp r7, #2 /* absolute fixup? */
beq fixabs
/* ignore unknown type of fixup */
b fixnext
fixabs:
/* absolute fix: set location to (offset) symbol value */
mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */
add r1, r10, r1 /* r1 <- address of symbol in table */
ldr r1, [r1, #4] /* r1 <- symbol value */
add r1, r1, r9 /* r1 <- relocated sym addr */
b fixnext
fixrel:
/* relative fix: increase location by offset */
ldr r1, [r0]
add r1, r1, r9
fixnext:
str r1, [r0]
add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
cmp r2, r3
blo fixloop
#endif
clear_bss:
#ifndef CONFIG_PRELOADER
ldr r0, _bss_start_ofs
ldr r1, _bss_end_ofs
mov r4, r6 /* reloc addr */
add r0, r0, r4
add r1, r1, r4
mov r2, #0x00000000 /* clear 清0 */
/*BSS段空间循环清0*/
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
bl coloured_LED_init
bl red_LED_on
#endif
/*
* We are done. Do not return, instead branch to second part of board
* initialization, now running from RAM.
*/
#ifdef CONFIG_NAND_SPL
ldr r0, _nand_boot_ofs
mov pc, r0 //进入nandflash启动的C主函数
_nand_boot_ofs:
.word nand_boot
#else
ldr r0, _board_init_r_ofs
adr r1, _start
add lr, r0, r1
add lr, lr, r9
/* setup parameters for board_init_r */
mov r0, r5 /* gd_t */
mov r1, r6 /* dest_addr */
/* jump to it ... */
mov pc, lr //进入C主函数
_board_init_r_ofs:
.word board_init_r - _start
#endif
_rel_dyn_start_ofs:
.word __rel_dyn_start - _start
_rel_dyn_end_ofs:
.word __rel_dyn_end - _start
*/
.word __dynsym_start - _start
转载请注明出处:http://www.cnblogs.com/zhangsufeng/archive/2011/08/11/2134362.html