我们要生成u-boot.bin文件,它首先依赖于很多.o文件和.lds链接脚本文件
我们只要找到对应的.lds链接脚本文件就可以分析u-boot的启动流程。
1、打开u-boot-1.1.6\u-boot-1.1.6\board\smdk2410\
打开链接脚本boot.lds 看看:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm920t/start.o (.text)
*(.text)
}
1)可以看见入口函数是_start
2)这个start代码放在cpu/arm920t/,就是start.S生成的start.o
2、打开u-boot-1.1.6\cpu\arm920t\start.S
.globl _start
_start: b reset
ldr pc, _undefined_instruction
......
一开始跳到 reset
reset:
设置CPU SVC32模式:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f /*clear 0 at low 5 bit */
orr r0,r0,#0xd3 /*set 110 10011*/
/*close irq,fiq,at arm state ,at supervisor mode */
msr cpsr,r0 /*write cpsr*/
I F 为1,关闭FIQ,IRQ
T为0,ARM模式
M[4:0]=10011,管理模式
关闭看门狗:
向pWTCON全写0
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
关闭所有中断:
但默认已经是关闭的
INTMSK写1,屏蔽对应的中断(默认1)
INTSUBMSK写1,屏蔽对应的二级中断(默认1)
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
设置时钟分频比:
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
接着跳入cpu系统初始化:
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
在里面再跳入sdram初始化:
bl lowlevel_init
拷贝代码到SDRAM:
十分遗憾,这是给NOR FLASH用的
首先判断_start当前第一条代码位置,如果是在内存中,就不用代码重定位了
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
设置堆栈:
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
还有设置中断stack
......
清bss段:
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
ble clbss_l
跳到c函数入口:
ldr pc, _start_armboot
_start_armboot: .word start_armboot
第一阶段基本完成
ldr绝对跳转到_start_armboot函数入口