u-boot-2016.11 uboot启动简易分析(基于S5PV210)

时间:2022-01-11 17:01:12

1、_start

_start是u-boot启动后的第一个执行地址,对于armv7来说,它就是简单的跳转到rest处执行和初始化异常向量表

vim arch/arm/lib/vectors.S

_start:

#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
.word CONFIG_SYS_DV_NOR_BOOT_CFG
#endif

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
2、reset

vim arch/arm/cpu/armv7/start.S

reset:
/* Allow the board to save important registers */
b save_boot_params
save_boot_params_ret:
#ifdef CONFIG_ARMV7_LPAE
/*
* check for Hypervisor support
*/
mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1
and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT)
beq switch_to_hypervisor
switch_to_hypervisor_ret:
#endif
/*
* 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/*
* Setup vector:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
* Continue to use ROM code vector only in OMAP4 spl)
*/
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
bic r0, #CR_V @ V = 0
mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register

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

/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15
#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
bl cpu_init_crit
#endif
#endif

bl _main
执行cpu底层的初始化,bl cpu_init_crit 调用了lowlevel_init(board/samsung/smdkv210/lowlever.S)
然后跳转到crt0.S中的main函数

3、_main

vim arch/arm/lib/crt0.S 
ENTRY(_main)/* * Set up initial C runtime environment and call board_init_f(0). *//* modied by Sourcelink */#if !defined(CONFIG_SPL_BUILD)        ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */        mov     r0, sp        bl      board_init_f_alloc_reserve        mov     sp, r0        /* set up gd here, outside any C code */        mov     r9, r0        bl      board_init_f_init_reserve        mov     r0, #0#endif/* modied by Sourcelink */#ifdef CONFIG_SPL_BUILD        bl      copy_bl2_to_ram                 /* 拷贝BL2到DDR */        ldr     pc, =CONFIG_SYS_SDRAM_BASE      /* 跳转到DDR的起始地址执行BL2 */#else        bl      board_init_f#endif#if ! defined(CONFIG_SPL_BUILD)/* * Set up intermediate environment (new sp and gd) and call * relocate_code(addr_moni). Trick here is that we'll return * 'here' but relocated. */        ldr     sp, [r9, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */#if defined(CONFIG_CPU_V7M)     /* v7M forbids using SP as BIC destination */        mov     r3, sp        bic     r3, r3, #7        mov     sp, r3#else        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */#endif        ldr     r9, [r9, #GD_BD]                 /* r9 = gd->bd */        sub     r9, r9, #GD_SIZE                /* new GD is below bd */        adr     lr, here        ldr     r0, [r9, #GD_RELOC_OFF]         /* r0 = gd->reloc_off */        add     lr, lr, r0#if defined(CONFIG_CPU_V7M)        orr     lr, #1                          /* As required by Thumb-only */#endif        ldr     r0, [r9, #GD_RELOCADDR]         /* r0 = gd->relocaddr */        b       relocate_codehere:/* * now relocate vectors */        bl      relocate_vectors/* Set up final (full) environment */        bl      c_runtime_cpu_setup     /* we still call old routine here */#endif#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)# ifdef CONFIG_SPL_BUILD        /* Use a DRAM stack for the rest of SPL, if requested */        bl      spl_relocate_stack_gd        cmp     r0, #0        movne   sp, r0        movne   r9, r0# endif        ldr     r0, =__bss_start        /* this is auto-relocated! */#ifdef CONFIG_USE_ARCH_MEMSET        ldr     r3, =__bss_end          /* this is auto-relocated! */        mov     r1, #0x00000000         /* prepare zero to clear BSS */        subs    r2, r3, r0              /* r2 = memset len */        bl      memset#else        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 */#if defined(CONFIG_CPU_V7M)        itt     lo#endif        strlo   r2, [r0]                /* clear 32-bit BSS word */        addlo   r0, r0, #4              /* move to next */        blo     clbss_l#endif#if ! defined(CONFIG_SPL_BUILD)        bl coloured_LED_init        bl red_led_on#endif        /* 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 */#if defined(CONFIG_SYS_THUMB_BUILD)        ldr     lr, =board_init_r       /* this is auto-relocated! */        bx      lr#else        ldr     pc, =board_init_r       /* this is auto-relocated! */#endif        /* we should not return here. */#endifENDPROC(_main)

1)设置c代码运行环境,为调用board_init_f接口做准备:

a) 先设置了堆栈指针。

b)调用board_init_f_alloc_reserve函数,从堆栈开始的地方,为u-boot中的global data 分配内存空间

c)调用board_init_f_init_reserve函数,对gd进行初始化

d)这两个函数都在common/init/board_init.c中

2)调用board_init_f函数,依次调用数组init_sequence_f中的函数完成前期的初始化工作:

a)主要调用init_baud_rate设置了串口波特率(common/board_f.c),接着调用serial_init初始化了串口(drivers/serial/serial.c)

b)调用display_options可以通过串口打印一些信息(lib/display_options.c)

c)调用printf_cpuinfo 答应cpu信息时钟和soc信号等(arch/arm/cpu/armv7/s5p-common/cpu_info.c)

3) 重新设置堆栈指针和gd -->重定位代码-->清除bss段-->点亮一个指示灯(自行添加 common/board_f.c)

4)调用board_init_r函数完成后续初始化工作(common/board_r.c)。