lowlevel_init看名字就知道是关于初级方面的初始化,其中可用将其干的事情分为11个步骤:
(1)push {lr} 也就是lr压栈。
(2)检测复位状态:如冷上电、热启动、睡眠等。冷上电要初始化DDR后才能使用但是后面的两种不需要。
(3)IO恢复。
(4)关看门狗。
(5)初始化SROM/SRAM(外部SRAM)。
(6)PS_HOLD 锁存供电(分为两步。写成一步非法立即数不行)。
(7)判断代码是否要重定位(当前代码在SRAM还是DDR中)运行状态是否等于链接地址。
①BL1代码在SRAM中与DDR中各有一份。如果是冷启动,代码在SRAM中,若是低功耗将会在DDR中(系统以前完整启动过)。
②判定当前地址可用,指导后面内容运行。主要就是要不要进行时钟或者DDR的初始化。代码在SRAM中->冷启动->初始化DDR与clock。代码在DDR中->热启动->不初始化后面的DDR与clock。
beq 1f 如果相等就会跳转到下方的1标号处
beq 1b 如果相等就会跳转到上方的1标号处
运行地址是否等于链接地址的方法,对于x210而言是这样的:首先
bic r1 ,pc ,r0 (其中r0=0xff000fff)
目的是将pc的值取出,去除掉r0表示为1的位值,剩下的赋值给r1
r1=pc(&~(ff000fff))
ldr r2 ,_TEXT_BASE(C3E00000)这个值是ddr的链接地址
bic r2,r2,r0
r2=r2&~(ff000fff)
cmp r1 ,r2 比较r1和r2
eg:(SRAM) pc=D0023456 TEXT_BASE=C3E00000
(DDR) pc=C3E03456 TEXT_BASE=C3E00000
比较pc的C3E与TEXT_BASE的C3E。
(8)初始化时钟,system_clock_init(相关宏在x210_sd.h中)。
(9)初始化内存,mem_ctrl_asm_init(DDR)。裸机中DMC0地址为0x20000000-0x2fffffff。uboot中可用物理地址为0x30000000-0x3fffffff。DMC0允许地址是0x20000000-0x3fffffff(一共512MB)。uboot中可用的物理地址为0x30000000-0x4fffffff,其中0x30000000-3fffffff为DMC0,0x40000000-4fffffff为DMC1。
(10)初始化串口urat_asm_init。
(11)tzpc_init (trust zone可信任区域初始化)。
lowlevel_init.S执行完成完成OK的打印,其中O在串口初始化完成时打印,K在tzpc_init执行完成后打印。
lowlevel_init执行完成。
这里提一下代码二次开发的一个原则:原来的代码不需要了可用使用注释的方式实其不编译,而不是进行删除,且尽可能别重复。
下一篇文章将继续对uboot的代码进行解析,下篇文章将开始于对栈的二次设置,敬请期待。