uboot启动第一阶段——start.S

一:引入start.S

    u-boot整个程序的入口取决于链接脚本u-boot.lds中ENTRY声明的地方。ENTRY(_start)因此 _start符号是整个程序的入口。

二:分析start.S

    

从SD卡和nand启动是需要16字节校验头(mkv210image.c就是为了计算这个校验头),dnw下载方式不需要校验头。这16字节在目前只能起到占位的功能,内容是不对的,还需要后面去计算校验和填充。

构建异常向量表,这个异常表顺序是CPU设计时决定的,是硬件决定的。这些异常应该被处理,如果不处理这些这些异常,程序会跑飞。复位异常的代码是 b reset ,因此在CPU复位后真正去执行的有效代码是reset处的代码,因此reset符号处,才是真正有意义代码的开始处。

异常处理程序指针。其中,.balignl 16,0xdeadbeef  .balignl 16 是以16字节对齐,如果没有对齐,用0xdeadbeef这个数字来填充,这个填充没有什么特别的意义。为什么要对齐呢?有时候是为了提高访问效率,有时候是硬件的要求。

TEXT_BASE在makefile配置阶段@echo "TEXT_BASE = 0xc3e00000" > $(obj)board/samsung/x210/config.mk进行设置的。这就是我们指定程序的链接地址,这是一个虚拟地址。

CFG_PHY_UBOOT_BASE也是链接地址,但是和TEXT_BASE不同的是,CFG_PHY_UBOOT_BASE是物理地址。

armboot_start后面重定位的时候会用到。_bss_start是bss段的起始地址,_bss_end是bss段的结束地址。

后面就开始真正分析,启动之后开始运行的程序reset

设置CPU运行SVC模式,禁止IRQ和FIQ。其实s5pv210上电默认就是在SVC模式,这里用软件重新设置一下,是为了保证代码的完整性,兼容更多的硬件。

设置L2 cache

刷新icache和dcache

关闭MMU

读取启动信息,并且判断启动方式。最后将判断出来的启动方式存进专门用来存储信息的寄存器中。

在sram中设置栈指针,因为马上要开始调用C语言函数

调用C语言函数,用于初始化底层外设,包括关看门狗、时钟、DDR和串口。这部分完全属于裸机层面的开发,这里不展开分析。

这个是开发板供电锁存,具体看开发板的设计,不用太纠结于此

再一次设置栈指针,由于之前已经初始化过DDR,因此现在可以将栈指针设置到DDR中,内存更大了。

判断在sram中运行还是在DDR中运行,如果在sram中运行则表示冷启动。冷启动的情况下需要对代码进行重定位,反之不要。

判断启动方式,准备从启动介质中将代码重定位到DDR中

假设我们是从SD卡中启动uboot的,我们的程序就会跳转到mmcsd_boot进行运行

这部分代码就是将uboot从SD卡中将程序拷贝到DDR中,然后跳转到after_copy

设置转换表基地址,并且使能MMU。以后再操作内存的时候,就将使用虚拟内存地址。转换表基地址具体怎么设置不做分析,但是为了以后分析方便,将对应关系给出来

重新设置栈指针,这次将栈指针设置到uboot上方2MB的地方,使得内存规划地更加紧凑,之后开始清理bss段。

万事具备之后,使用一个远跳转,跳转到DDR中去运行。

至此uboot第一部分的使命就结束了。

猜你喜欢

转载自blog.csdn.net/lushoumin/article/details/82854466