总结下手中开发板的启动过程,uboot版本为2014.07,参考S5P6818 Application Processor User's Manual。
首先,我们应该知道为什么需要uboot,而不是只知其然,不知其所以然。一言以概之:在我们能够在操作系统下运行程序之前,所有的努力都是为了能够让系统能够被搬运到内存中运行。有了这样的目的性,我们分析理解起来就简单多了。
其实,高端的ARM芯片并不和STM32等Cortex-M系的ARM芯片相差很多,只是主频更高,核心增多,外设更丰富了。附图吧:
IROM:
和大部分ARM芯片一样,S5P6818内部也自带了RAM和ROM,分别为64K和20K。若官方提供下载器的话,我们也可以像STM32一样,让代码在ROM中运行,RAM中保存堆栈变量等信息,但那就大材小用了。显然,为了能够跑起linux,光是芯片内的这点空间是完全不够的,好在高端芯片强就强在能够带动大容量的外部RAM和ROM。所以我们一般会将系统存放在外部的SD卡或EMMC中。所以我们此时我们的目的也很明确,检查外部的存储中是否包含合法的内容。
因此,在系统上电后,芯片首先会运行片内20KB ROM中的代码,此ROM一般为NOR FLASH。相对于外部存储经常使用的NAND FLASH,其优势在于代码可以芯片内运行,所以不需要像NAND FLASH一样将代码搬运到内存中。内部ROM地址一般即为0地址处,其作用是检测引脚的配置情况,确定外部存储器启动的优先级,选择对应的外部存储进行初始化,再将其中的前56K代码搬运到内部RAM中(因内部RAM只有64KB,且ROM自身会用掉一部分RAM),当搬运了512字节之后会进行Boot Header的检查,查看签名是否为0x4849534E。若是,则为正确代码,跳转到内部RAM即地址0xFFFF0000处运行;否则,选择下一个外部存储器进行判断测试。
如图,若想系统首先从SDMMC启动,则须将RST_CFG[2:0]这三位设置为5,这三位对应于原理图为SD2,SD1和SD0,从原理图可以看出我们确实是这样设置了。
之后还可以通过SD3和CAM1_D3进行从哪一个SDMMC进行启动,共有三个端口可选。接下来就是从SD卡中复制代码到内部RAM中并跳转运行了,如图。
2ndboot:
现在的状态是外部存储器可以读取使用了,但外部的大容量SDRAM还是不能使用,而我们最终的目的是要将代码放入到SDRAM中运行的,这里讲讲SRAM和DRAM的区别。S和D分别代表静态和动态刷新,SRAM在上电后只要不断电数据就一直存在,而DRAM需要在上电后过一段时间进行充电刷新,这样数据才能够保持不变,虽然相比SRAN变麻烦了,但价格降低,容量却提升了。这就是S5P6818内部采用小容量SRAM,外面挂接DDR3这样的SDRAM的原因,这里的S为串行的意思。所以现在很明确加载到内部SRAM中代码所需要做的事了:1、初始化芯片的内存控制器 2、初始化外部SDRAM 3、将SD卡中uboot搬运到内存中运行。
当然除此之外,还有包括设置中断向量表,设置PLL,设置堆栈,初始化串口等,这就是s5p6818提供的2ndboot的内容,烧写在SD卡的block1~block64共32K字节的位置。
以往这部分内容也有是在uboot中进行完成的,在接下来的uboot讲解中会有提到,把这部分初始化的内容提炼提炼出来的好处就是减少了uboot的自搬运过程。
uboot:
2ndboot最后的动作便是将uboot从SD卡的第65块block搬运到内存0x42C00000的位置,接下来便会跳转到外部SDRAM进行uboot的运行。
首先查看生成的uboot链接文件uboot.lds:
可知此uboot程序代码起始的运行位置为arch/arm/cpuslsiap/s5p6818/start.o的_stext处。
/*
*************************************************************************
*
* Exception vectors as described in ARM reference manuals
*
* replace arm/lib/vectors.S
*
*************************************************************************
*/
.globl _stext
_stext:
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0x