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

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_code
here:
/*
 * 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. */
#endif

ENDPROC(_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)。






你可能感兴趣的:(u-boot)