U-boot启动的代码分析:
boot.lds 规定了所有编译后的.o 文件的链接方式,所有的.c 文件编译后都会生成一个.o 文件,.o 文件然后再按lds 规定的顺序将各自相同的数据段整合到一起生成一个ELF 文件。将ELF的头拿掉就生成一个.系统可执行的.bin 文件
当系统上电的时候,CPU中的固件(在CPU出厂前就已经烧录到CPU中,用于支持特定型号的Nand Flash)会将我们已经烧录到Nand Flash中的uboot.bin的前4K代码拷贝到CPU片内的SRAM中执行。
这前4K代码会执行如下任务
1>进入SVC模式
2>关闭看门狗
3>屏蔽所以的中断
4>设置CPU的速度和频率
5>关闭CPU内部的MMU和CACHE
6>初始化SDRAM
7>把Nand Flash中的uboot后4K的代码拷贝到SDRAM中
8>清.bss段
9>跳入SDRAM中的真正的第一个C函数start_armboot()
首先我们要了解的框架来自于uboot.lds,boot.lds是告诉编译器这段该以怎样的顺序链接
SECTIONS
{
. = 0x33F80000; //左边的.表示设置当前属性
__start = . ; //右边的.表示当前链接的地址
.text : //text指代码段
{
start.o (.text) //这里把start.o放在第一位就表示把start.s编译时放在最开始,这就是为什么把uboot烧到起始位置上它肯定运行的是start.s
clock.o (.text)
sdram.o (.text)
nand.o (.text)
* (.text)
}
. = ALIGN(4); //前面的“.”代表当前值,是计算一个当前的值,是计算上面占用的整个空间,再加一个单元就表示它现在的位置,按四个字节对齐
.rodata : //只读数据段
{
* (.rodata)
}
. = ALIGN(4);
.data : //数据段,全局变量
{
* (.data)
}
. = ALIGN(4);
__bss_start = .; //bss表示归零段
.bss :
{
* (.bss)
}
. = ALIGN(4);
__bss_end = .;
__end = .;
}
2、初始化的各文件
2.1> start.S
globl _start
_start:
/* 1. 硬件相关的设置 */
/*1.1 设置CPU的工作模式为SVC,cpsr[4:0]=10011;cpsr[7:5]=110,CPSR[7:0]=0x11010011*/
mrs r0 , cpsr //msr:将状态寄存器CPSR&SPSR读出到通用寄存器
bic r0 , r0 , #0x1f //bic:位清零,r0&=~(0x1f),r0[4:0]=0x0
orr r0 , r0 , #0xd3 //orr:逻辑或,r0|=(0xd3),r0[7:0]=0x11010011
msr cpsr , r0 //msr:将通用寄存器读出到状态寄存器CPSR&SPSR
/*1.2 关闭看门狗,否则在U-boot启动过程中,CPU将不断重启*/
ldr r0, =0x53000000 //ldr:从内存中将一个32位的字读取到目标寄存器,WTCON=0X53000000
ldr r1, =0
str r1, [r0] //str:将一个32位的字数据写入到指令中指定的内存单元,将r1保存到地址[r0]中,[r0]=r1
/*1.3 关闭中断*/
ldr r0 , =0x4a000008 //主中断屏蔽寄存器(32位,每位对应一个中断):INTMASK:0x4A000008,复位值0xFFFFFFFF屏蔽所有中断源
ldr r1 , =0xffffffff
str r1 , [r0]
ldr r0 , =0x4a00001c //次中断屏蔽寄存器(32位,[14:0]有效):INTSUBMSK:0x4A00001c,复位值0x7FFF
ldr r1 , =0x7fff
str r1 , [r0]
/*1.4. 代码中的c0,c1,c7,c8都是ARM920T的协处理器