uboot代码初始化执行顺序

uboot相关文件

boards.cfg

1
2
3
4
5
6
7
8
9
ARCH = ARM

CPU = ARMv7

SOC = exynos

BOARD = smdkc210

VENDER = samsung

files

1
2
3
4
5
6
7
8
9
10
11
Include/configs/smdkc210.h

arch/$(ARCH)/cpu/$(CPU)/start.S

board/$(VENDER)/$(BOARD)/smdkc210.c

arch/$(ARCH)/lib/board.c

arch/$(ARCH)/lib/crto.S

arch/$(ARCH)/lib/relocate.S

初始化流程

  1. start.S -> _start
  2. start.S -> reset
  3. crt0.S -> _main ==>> board.c -> board_init_f
  4. relocate.S -> relocate_code
  5. crt0.S -> here
  6. board.c -> board_init_r
  7. main.c -> main_loop

初始化实现(ARM)

《ARM Cortex-A Series Programmer’s Guide》中列出了Cortex-A系列的初始化方法(第十三章:Boot Code)。

ARM启动时,会从异常向量表的reset异常处启动(0或0xffff0000)。对于u-boot,不需要实现所有启动流程,只需要实现几个必须的过程:

  1. Initialize exception vectors.
  2. Initialize the memory system, including the MMU.
  3. Initialize core mode stacks and registers.
  4. Initialize any critical I/O devices.
  5. Call the main()application.

初始化中断向量表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
.globl _start
_start: 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
_pad: .word 0x12345678 /* now 16*4=64 */

.global _end_vect
_end_vect:
.balignl 16,0xdeadbeef

ENTRY(cpu_init_cp15)
/*
* Invalidate L1 I/D cache (Initialize the memory system, including the MMU)
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB

/*

* disable MMU stuff and caches

*/

mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
mcr p15, 0, r0, c1, c0, 0
mov pc, lr @ back to my caller

禁止中断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    /* 禁止中断 (FIQ and IRQ), 设置CPU模式为SVC32 */
reset:
bl save_boot_params
/*
* disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
* except if in HYP mode already
*/
mrs r0, cpsr
and r1, r0, #0x1f @ mask mode bits
teq r1, #0x1a @ test for HYP mode
bicne r0, r0, #0x1f @ clear all mode bits
orrne r0, r0, #0x13 @ set SVC mode
orr r0, r0, #0xc0 @ disable FIQ and IRQ
msr cpsr,r0

设置中断向量表

1
2
3
4
5
6
7
8
/* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTRL Register
bic r0, #CR_V @ V = 0
mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTRL Register

/* Set vector address in CP15 VBAR register */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR

初始化MMU

1
2
3
4
5
6
7
8
9
10
ENTRY(cpu_init_cp15)
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB

禁止MMU

1
2
3
4
5
6
7
8
9
10
11
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
mcr p15, 0, r0, c1, c0, 0
mov pc, lr @ back to my caller

设置C运行环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ENTRY(_main)
/*
* Set up initial C runtime environment and call board_init_f(0).
*/
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
sub sp, #GD_SIZE /* allocate one GD above SP */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
mov r9, sp /* GD is above SP */

ENTRY(c_runtime_cpu_setup)
/*
* invalidate I-cache
*/
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB

初始化串口

1
2
mov    r0, #0
bl board_init_f

设置临时运行变量

1
2
3
4
5
6
7
8
9
/*
* Set up intermediate environment (new sp and gd) and call
* relocate_code(addr_moni). Trick here is that we'll retur
* 'here' but relocated.
*/
ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
sub r9, r9, #GD_SIZE /* new GD is below bd */

代码重定向

1
2
3
4
5
6
7
8
9
    /*
* 代码重定向,保证u-boot迁入内存后能够正常运行 (Relocate the code)
*/
adr lr, here
ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */
add lr, lr, r0
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
b relocate_code
here:

重定向向量表

1
2
3
4
5
6
7
8
9
10
/*
* Move vector table
* 由于u-boot经过了重定向,代码位置发生了改变,所以这里需要重新设置VBAR寄存器。
* 实际的代码如下:
* ldr r0, [pc, #736]
* 利用PC保证加载的是当前地址,而不是u-boot在ROM中的地址。
*/
/* Set vector address in CP15 VBAR register */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR

BSS段清零

1
2
3
4
5
6
7
8
    ldr    r0, =__bss_start    /* this is auto-relocated! */
ldr r1, =__bss_end /* this is auto-relocated! */
mov r2, #0x00000000 /* prepare zero to clear BSS */
clbss_l:
cmp r0, r1 /* while not at end of BSS */
strlo r2, [r0] /* clear 32-bit BSS word */
addlo r0, r0, #4 /* move to next */
blo clbss_l

进入main_loop

1
2
3
4
5
/* call board_init_r(gd_t *id, ulong dest_addr) */
mov r0, r9 /* gd_t */
ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */
/* call board_init_r */
ldr pc, =board_init_r /* this is auto-relocated! */

board_init_r的实现

Function 描述
arch_cpu_init SoC相关的cpu初始化
timer_init SoC上的时钟初始化
env_init 初始化环境变量, 实际上是把default_environment设置到gd->env_addr. default_environment是一个字符串数组,每一个字符串用一个宏表示,我们通过在“include/configs/smdkc210.h”定义这些宏的方式设置环境变量。
init_baudrate 设置波特率,其实它来自于 gd->baud.
serial_init 调用串口初始化函数
dram_init 设置RAM位置与大小
set_gd 设置gd表,用于保存配置

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 yxhlfx@163.com

文章标题:uboot代码初始化执行顺序

本文作者:红尘追风

发布时间:2016-07-15, 00:31:46

原始链接:http://www.micernel.com/2016/07/15/uboot%E4%BB%A3%E7%A0%81%E5%88%9D%E5%A7%8B%E5%8C%96%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录