硬件平台:tq2440
开发环境:Ubuntu-3.11
u-boot版本:2014.10
本文允许转载,请注明出处:http://blog.csdn.net/fulinus
接着第七天的代码分析,下面是cpu_init_crit的代码段,同样位于文件arch/arm/cpu/arm920t/start.S中:
/* *************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
#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
mov lr, ip
mov pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
mcr/mrc指令:http://blog.csdn.net/oyzhizhong/article/details/6967932
这段代码详见:http://blog.chinaunix.net/uid-11251862-id-2888834.html
协处理器说明: http://blog.csdn.net/skyflying2012/article/details/25823967
mov ip, lr //保存返回地址
bl lowlevel_init
mov lr, ip //还原返回地址
mov pc, lr //子函数返回
进入lowlevel_init子函数,该函数在board/samsung/smdk2410/lowlevel_init.S:
.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 ! */
ldr r0, =SMRDATA //r0保存SMRDATA的位置;
ldr r1, =CONFIG_SYS_TEXT_BASE //在文件include/configs/smdk2410.h中定义为#define CONFIG_SYS_TEXT_BASE 0x0
sub r0, r0, r1 // r0 = r0 - r1 = r0 - 0
ldr r1, =BWSCON /* Bus Width Status Controller */ //#define BWSCON 0x48000000
add r2, r0, #13*4 //r2 = r0 +13*4 13个寄存器,如图:
0:
ldr r3, [r0], #4 // r3 = *r0 , r0 = r0 + 4 ; 第一次循环时r3 = (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
str r3, [r1], #4 // *r1 = r3 , r1 + 4; 第一次循环时将上面r3的值写到BWSCON寄存器中。
cmp r2, r0 //判断r0与r2是否相等 , 13个寄存器
bne 0b //不相等就跳到0处,b不是向后跳。
/* everything is fine now */
mov pc, lr //返回
.ltorg
/* the literal pools origin */
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32
.word 0x30
.word 0x30
回到文件arch/arm/cpu/arm920t/start.S中,bl cpu_init_crit的下一条指令是
bl _main
上面这条指令跳转到了arch/arm/lib/crt0.S 文件中。明天继续
参考博文:http://blog.csdn.net/skyflying2012/article/details/25804209