u-boot原理分析第二课-------第一阶段系统初始化

    上节课说到了,u-boot的代码是从start.o开始的,所以我们这节课就来看start.s的代码:

我们看到,代码一开始就跳到了reset处,而其后面是一些中断和中断向量表的设置,我们直接看reset处的代码:

我们看到,这段代码里,首先先设置cpu为管理模式(svc),接着关闭看门狗。

我们接着看:

这里是屏蔽所有的IRQ中断。

接着看:

这里是设置时钟源

接着看:

这里是判断是复位还是唤醒。接下来的代码则是判断u-boot程序是不是从ram启动的。我们可以看到它的那句英文:

we do sys-critical initial only at reboot,not when booting from ram(我们只在重启时进行关键性的系统初始化,而不是在ram中启动时)。对于u-boot程序,可能在nand启动或nor启动,它的启动地址则是0,这时一般都没有对SDRAM进行初始化。但对于一些仿真器,调试器之类的直接下载到SDRAM中去的放,那这时r0就等于它的链接地址,即0x33F800。r1是_Text_Base,也就是33F800(链接脚本里有)   。cmp r0,r1判断这里两个值是否相等,如果不相等的话,说明程序是直接从Nand或者nor运行的,需要进行一些系统必要的初始化。接下来就跳到初始化的代码段去:


这里,首先先关Flush,清caches,然后再禁用MMU和caches,最后跳到了lowlevel_init这个函数里,我们看一下这个函数里做了什么:

_TEXT_BASE:
	.word	TEXT_BASE

.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
	ldr	r1, _TEXT_BASE
	sub	r0, r0, r1
	ldr	r1, =BWSCON	/* Bus Width Status Controller */
	add     r2, r0, #13*4
0:
	ldr     r3, [r0], #4
	str     r3, [r1], #4
	cmp     r2, r0
	bne     0b

	/* 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 0xb1
    .word 0x30
    .word 0x30

这段代码是在初始化内存控制器。初始化完成后,内存才能使用。

调用完这个函数后,cpu_init函数也返回了,我们继续看看它的执行过程:

首先,先进行栈的分配,然后,对代码进行重定位,定位到SDRAM中。

我们接着往下看:

这里是清除bss段,和设置运行参数。

最后,对于一些更复杂的初始化,则跳到了_start_armboot中去实现:

此前的所有初始化,都是一些硬件初始化,当换成其它CPU,初始化的具体内容就不一样了。我们把这一过程称做UBOOT的第一阶段

猜你喜欢

转载自blog.csdn.net/xiaokangdream/article/details/79498522
今日推荐