原博客:https://blog.csdn.net/xiaokangdream/article/details/79498522
上节课说到了,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的第一阶段