u-boot-2016.01分析s3c2410启动过程

首先从u-boot官网下载u-boot-2016.01.tar.gz的源码 ftp://ftp.denx.de/pub/u-boot/。解压然后配置顶层Makefile中的CROSS_COMPILE=”你的交叉编译器路径”后执行如下命令开始编译:

make smdk2410_defconfig
make 

编译成功后会在你的u-boot-2016.01文件夹下面生成u-boot.bin U-boot.lds等文件。

注意在新版u-boot中还有一个文件叫Config.mk源码如下:
你在make 的时候实际上是执行了Makefile正的语句

#
# (C) Copyright 2000-2013
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier:  GPL-2.0+
#
#########################################################################

# This file is included from ./Makefile and spl/Makefile.
# Clean the state to avoid the same flags added twice.
#
# (Tegra needs different flags for SPL.
#  That's the reason why this file must be included from spl/Makefile too.
#  If we did not have Tegra SoCs, build system would be much simpler...)
PLATFORM_RELFLAGS :=
PLATFORM_CPPFLAGS :=
PLATFORM_LDFLAGS :=
LDFLAGS :=
LDFLAGS_FINAL :=
OBJCOPYFLAGS :=
# clear VENDOR for tcsh
VENDOR :=
#########################################################################

ARCH := $(CONFIG_SYS_ARCH:"%"=%)
CPU := $(CONFIG_SYS_CPU:"%"=%)
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_TEGRA
CPU := arm720t
endif
endif
BOARD := $(CONFIG_SYS_BOARD:"%"=%)
ifneq ($(CONFIG_SYS_VENDOR),)
VENDOR := $(CONFIG_SYS_VENDOR:"%"=%)
endif
ifneq ($(CONFIG_SYS_SOC),)
SOC := $(CONFIG_SYS_SOC:"%"=%)
endif

# Some architecture config.mk files need to know what CPUDIR is set to,
# so calculate CPUDIR before including ARCH/SOC/CPU config.mk files.
# Check if arch/$ARCH/cpu/$CPU exists, otherwise assume arch/$ARCH/cpu contains
# CPU-specific code.
CPUDIR=arch/$(ARCH)/cpu$(if $(CPU),/$(CPU),)

sinclude $(srctree)/arch/$(ARCH)/config.mk  # include architecture dependend rules
sinclude $(srctree)/$(CPUDIR)/config.mk        # include  CPU  specific rules

ifdef   SOC
sinclude $(srctree)/$(CPUDIR)/$(SOC)/config.mk    # include  SoC  specific rules
endif
ifneq ($(BOARD),)
ifdef   VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
endif
endif
ifdef   BOARD
sinclude $(srctree)/board/$(BOARDDIR)/config.mk  # include board specific rules
endif

ifdef FTRACE
PLATFORM_CPPFLAGS += -finstrument-functions -DFTRACE
endif

# Allow use of stdint.h if available
ifneq ($(USE_STDINT),)
PLATFORM_CPPFLAGS += -DCONFIG_USE_STDINT
endif

#########################################################################

RELFLAGS := $(PLATFORM_RELFLAGS)

PLATFORM_CPPFLAGS += $(RELFLAGS)
PLATFORM_CPPFLAGS += -pipe

LDFLAGS += $(PLATFORM_LDFLAGS)
LDFLAGS_FINAL += -Bstatic

export PLATFORM_CPPFLAGS
export RELFLAGS
export LDFLAGS_FINAL
export CONFIG_STANDALONE_LOAD_ADDR

U-boot.lds是一个连接文件贴上他的源码如下:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")/*指定输出ELF 32位ARM指令 小端 格式*/
OUTPUT_ARCH(arm)/*指定输出平台为ARM*/
ENTRY(_start)/*指定程序的入口是 _start*/
SECTIONS 
{
 /DISCARD/ : { *(.rel._secure*) }
 . = 0x00000000;
 . = ALIGN(4);
 .text :
 {
  *(.__image_copy_start)
  *(.vectors)
  arch/arm/cpu/arm920t/start.o (.text*)
  *(.text*)
 }
 . = ALIGN(4);
 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
 . = ALIGN(4);
 .data : {
  *(.data*)
 }
 . = ALIGN(4);
 . = .;
 . = ALIGN(4);
 .u_boot_list : {
  KEEP(*(SORT(.u_boot_list*)));
 }
 . = ALIGN(4);
 .image_copy_end :
 {
  *(.__image_copy_end)
 }
 .rel_dyn_start :
 {
  *(.__rel_dyn_start)
 }
 .rel.dyn : {
  *(.rel*)
 }
 .rel_dyn_end :
 {
  *(.__rel_dyn_end)
 }
 .end :
 {
  *(.__end)
 }
 _image_binary_end = .;
 . = ALIGN(4096);
 .mmutable : {
  *(.mmutable)
 }
 .bss_start __rel_dyn_start (OVERLAY) : {
  KEEP(*(.__bss_start));
  __bss_base = .;
 }
 .bss __bss_base (OVERLAY) : {
  *(.bss*)
   . = ALIGN(4);
   __bss_limit = .;
 }
 .bss_end __bss_limit (OVERLAY) : {
  KEEP(*(.__bss_end));
 }
 .dynsym _image_binary_end : { *(.dynsym) }
 .dynbss : { *(.dynbss) }
 .dynstr : { *(.dynstr*) }
 .dynamic : { *(.dynamic*) }
 .plt : { *(.plt*) }
 .interp : { *(.interp*) }
 .gnu.hash : { *(.gnu.hash) }
 .gnu : { *(.gnu*) }
 .ARM.exidx : { *(.ARM.exidx*) }
 .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}

知道了程序的入口地址是 _start后我们就先找到这个入口具体在那个文件里面:u-boot-2016.01/arch/arm/lib/vectors .S 打开文件查看源码如下:

/*
 *  vectors - Generic ARM exception table code
 *
 *  Copyright (c) 1998  Dan Malek <dmalek@jlc.net>
 *  Copyright (c) 1999  Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
 *  Copyright (c) 2000  Wolfgang Denk <wd@denx.de>
 *  Copyright (c) 2001  Alex Z眉pke <azu@sysgo.de>
 *  Copyright (c) 2001  Marius Gr枚ger <mag@sysgo.de>
 *  Copyright (c) 2002  Alex Z眉pke <azu@sysgo.de>
 *  Copyright (c) 2002  Gary Jennejohn <garyj@denx.de>
 *  Copyright (c) 2002  Kyle Harris <kharris@nexus-tech.net>
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include <config.h>

/*
 *************************************************************************
 *
 * Symbol _start is referenced elsewhere, so make it global
 *
 *************************************************************************
 */

.globl _start

/*
 *************************************************************************
 *
 * Vectors have their own section so linker script can map them easily
 *
 *************************************************************************
 */

    .section ".vectors", "ax"

/*
 *************************************************************************
 *
 * Exception vectors as described in ARM reference manuals
 *
 * Uses indirect branch to allow reaching handlers anywhere in memory.
 *
 *************************************************************************
 */

_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

/*
 *************************************************************************
 *
 * Indirect vectors table
 *
 * Symbols referenced here must be defined somewhere else
 *
 *************************************************************************
 */

    .globl  _undefined_instruction
    .globl  _software_interrupt
    .globl  _prefetch_abort
    .globl  _data_abort
    .globl  _not_used
    .globl  _irq
    .globl  _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

    .balignl 16,0xdeadbeef

/*
 *************************************************************************
 *
 * Interrupt handling
 *
 *************************************************************************
 */

/* SPL interrupt handling: just hang */

#ifdef CONFIG_SPL_BUILD

    .align  5
undefined_instruction:
software_interrupt:
prefetch_abort:
data_abort:
not_used:
irq:
fiq:

1:
    bl  1b          /* hang and never return */

#else   /* !CONFIG_SPL_BUILD */

/* IRQ stack memory (calculated at run-time) + 8 bytes */
.globl IRQ_STACK_START_IN
IRQ_STACK_START_IN:
    .word   0x0badc0de

#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
    .word   0x0badc0de

/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
    .word 0x0badc0de

#endif /* CONFIG_USE_IRQ */

@
@ IRQ stack frame.
@
#define S_FRAME_SIZE    72

#define S_OLD_R0    68
#define S_PSR       64
#define S_PC        60
#define S_LR        56
#define S_SP        52

#define S_IP        48
#define S_FP        44
#define S_R10       40
#define S_R9        36
#define S_R8        32
#define S_R7        28
#define S_R6        24
#define S_R5        20
#define S_R4        16
#define S_R3        12
#define S_R2        8
#define S_R1        4
#define S_R0        0

#define MODE_SVC 0x13
#define I_BIT    0x80

/*
 * use bad_save_user_regs for abort/prefetch/undef/swi ...
 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
 */

    .macro  bad_save_user_regs
    @ carve out a frame on current user stack
    sub sp, sp, #S_FRAME_SIZE
    stmia   sp, {r0 - r12}  @ Save user registers (now in svc mode) r0-r12
    ldr r2, IRQ_STACK_START_IN
    @ get values for "aborted" pc and cpsr (into parm regs)
    ldmia   r2, {r2 - r3}
    add r0, sp, #S_FRAME_SIZE       @ grab pointer to old stack
    add r5, sp, #S_SP
    mov r1, lr
    stmia   r5, {r0 - r3}   @ save sp_SVC, lr_SVC, pc, cpsr
    mov r0, sp      @ save current stack into r0 (param register)
    .endm

    .macro  irq_save_user_regs
    sub sp, sp, #S_FRAME_SIZE
    stmia   sp, {r0 - r12}          @ Calling r0-r12
    @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
    add r8, sp, #S_PC
    stmdb   r8, {sp, lr}^       @ Calling SP, LR
    str lr, [r8, #0]        @ Save calling PC
    mrs r6, spsr
    str r6, [r8, #4]        @ Save CPSR
    str r0, [r8, #8]        @ Save OLD_R0
    mov r0, sp
    .endm

    .macro  irq_restore_user_regs
    ldmia   sp, {r0 - lr}^          @ Calling r0 - lr
    mov r0, r0
    ldr lr, [sp, #S_PC]         @ Get PC
    add sp, sp, #S_FRAME_SIZE
    subs    pc, lr, #4      @ return & move spsr_svc into cpsr
    .endm

    .macro get_bad_stack
    ldr r13, IRQ_STACK_START_IN     @ setup our mode stack

    str lr, [r13]   @ save caller lr in position 0 of saved stack
    mrs lr, spsr    @ get the spsr
    str lr, [r13, #4]   @ save spsr in position 1 of saved stack
    mov r13, #MODE_SVC  @ prepare SVC-Mode
    @ msr   spsr_c, r13
    msr spsr, r13   @ switch modes, make sure moves will execute
    mov lr, pc      @ capture return pc
    movs    pc, lr      @ jump to next instruction & switch modes.
    .endm

    .macro get_irq_stack            @ setup IRQ stack
    ldr sp, IRQ_STACK_START
    .endm

    .macro get_fiq_stack            @ setup FIQ stack
    ldr sp, FIQ_STACK_START
    .endm

/*
 * exception handlers
 */

    .align  5
undefined_instruction:
    get_bad_stack
    bad_save_user_regs
    bl  do_undefined_instruction

    .align  5
software_interrupt:
    get_bad_stack
    bad_save_user_regs
    bl  do_software_interrupt

    .align  5
prefetch_abort:
    get_bad_stack
    bad_save_user_regs
    bl  do_prefetch_abort

    .align  5
data_abort:
    get_bad_stack
    bad_save_user_regs
    bl  do_data_abort

    .align  5
not_used:
    get_bad_stack
    bad_save_user_regs
    bl  do_not_used

#ifdef CONFIG_USE_IRQ

    .align  5
irq:
    get_irq_stack
    irq_save_user_regs
    bl  do_irq
    irq_restore_user_regs

    .align  5
fiq:
    get_fiq_stack
    /* someone ought to write a more effiction fiq_save_user_regs */
    irq_save_user_regs
    bl  do_fiq
    irq_restore_user_regs

#else

    .align  5
irq:
    get_bad_stack
    bad_save_user_regs
    bl  do_irq

    .align  5
fiq:
    get_bad_stack
    bad_save_user_regs
    bl  do_fiq

#endif /* CONFIG_USE_IRQ */

#endif  /* CONFIG_SPL_BUILD */

可以看出主要是定义了ARM异常向量的地址和出现异常时所调用的处理函数的入口地址。这段代码执行的第一条汇编指令是:b reset跳转到reset处,那么reset在哪里呢,他在如下路径:u-boot-2016-01/arch/arm/cpu/arm920t/start.S 其源码如下:

/*
 *  armboot - Startup Code for ARM920 CPU-core
 *
 *  Copyright (c) 2001  Marius Gr枚ger <mag@sysgo.de>
 *  Copyright (c) 2002  Alex Z眉pke <azu@sysgo.de>
 *  Copyright (c) 2002  Gary Jennejohn <garyj@denx.de>
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include <asm-offsets.h>
#include <common.h>
#include <config.h>

/*
 *************************************************************************
 *
 * Startup Code (called from the ARM reset exception vector)
 *
 * do important init only if we don't start from memory!
 * relocate armboot to ram
 * setup stack
 * jump to second stage
 *
 *************************************************************************
 */

    .globl  reset

reset:
    /*
     * set the cpu to SVC32 mode
     */
    mrs r0, cpsr
    bic r0, r0, #0x1f
    orr r0, r0, #0xd3
    msr cpsr, r0

#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
    /*
     * relocate exception table
     */
    ldr r0, =_start
    ldr r1, =0x0
    mov r2, #16
copyex:
    subs    r2, r2, #1
    ldr r3, [r0], #4
    str r3, [r1], #4
    bne copyex
#endif

#ifdef CONFIG_S3C24X0
    /* turn off the watchdog */

# if defined(CONFIG_S3C2400)
#  define pWTCON    0x15300000
#  define INTMSK    0x14400008  /* Interrupt-Controller base addresses */
#  define CLKDIVN   0x14800014  /* clock divisor register */
#else
#  define pWTCON    0x53000000
#  define INTMSK    0x4A000008  /* Interrupt-Controller base addresses */
#  define INTSUBMSK 0x4A00001C
#  define CLKDIVN   0x4C000014  /* clock divisor register */
# endif

    ldr r0, =pWTCON
    mov r1, #0x0
    str r1, [r0]

    /*
     * 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]
#endif  /* CONFIG_S3C24X0 */

    /*
     * we do sys-critical inits only at reboot,
     * not when booting from ram!
     */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl  cpu_init_crit
#endif

    bl  _main

/*------------------------------------------------------------------------------*/

    .globl  c_runtime_cpu_setup
c_runtime_cpu_setup:

    mov pc, lr

/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */


#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
    /*
     * flush v4 I/D caches
     */
    mov r0, #0
    mcr p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */
    mcr p15, 0, r0, c8, c7, 0   /* flush v4 TLB */

    /*
     * disable MMU stuff and caches
     */
    mrc p15, 0, r0, c1, c0, 0
    bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
    bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
    orr r0, r0, #0x00000002 @ set bit 2 (A) Align
    orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
    mcr p15, 0, r0, c1, c0, 0

    /*
     * before relocating, we have to setup RAM timing
     * because memory timing is board-dependend, you will
     * find a lowlevel_init.S in your board directory.
     */
    mov ip, lr

    bl  lowlevel_init

    mov lr, ip
    mov pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */

该文件主要作用是:分别为
(1)配置系统为SVC32模式,
(2)屏蔽所有中断
(3)设置系统时钟
(4)如果没有定义CONFIG_SKIP_LOWLEVEL_INIT那么就到cpu_init_crit 设置caches,关闭MMU,初始化内存
(5)最后跳转到 _main入口。

_main入口在什么地方呢,他的路径为:u-boot-2016.01/arch/arm/lib/crt0.S 中其源码如下:

/*
 *  crt0 - C-runtime startup Code for ARM U-Boot
 *
 *  Copyright (c) 2012  Albert ARIBAUD <albert.u.boot@aribaud.net>
 *
 * SPDX-License-Identifier: GPL-2.0+
 */

#include <config.h>
#include <asm-offsets.h>
#include <linux/linkage.h>
#ifdef CONFIG_CPU_V7M
#include <asm/armv7m.h>
#endif

/*
 * This file handles the target-independent stages of the U-Boot
 * start-up where a C runtime environment is needed. Its entry point
 * is _main and is branched into from the target's start.S file.
 *
 * _main execution sequence is:
 *
 * 1. Set up initial environment for calling board_init_f().
 *    This environment only provides a stack and a place to store
 *    the GD ('global data') structure, both located in some readily
 *    available RAM (SRAM, locked cache...). In this context, VARIABLE
 *    global data, initialized or not (BSS), are UNAVAILABLE; only
 *    CONSTANT initialized data are available. GD should be zeroed
 *    before board_init_f() is called.
 *
 * 2. Call board_init_f(). This function prepares the hardware for
 *    execution from system RAM (DRAM, DDR...) As system RAM may not
 *    be available yet, , board_init_f() must use the current GD to
 *    store any data which must be passed on to later stages. These
 *    data include the relocation destination, the future stack, and
 *    the future GD location.
 *
 * 3. Set up intermediate environment where the stack and GD are the
 *    ones allocated by board_init_f() in system RAM, but BSS and
 *    initialized non-const data are still not available.
 *
 * 4a.For U-Boot proper (not SPL), call relocate_code(). This function
 *    relocates U-Boot from its current location into the relocation
 *    destination computed by board_init_f().
 *
 * 4b.For SPL, board_init_f() just returns (to crt0). There is no
 *    code relocation in SPL.
 *
 * 5. Set up final environment for calling board_init_r(). This
 *    environment has BSS (initialized to 0), initialized non-const
 *    data (initialized to their intended value), and stack in system
 *    RAM (for SPL moving the stack and GD into RAM is optional - see
 *    CONFIG_SPL_STACK_R). GD has retained values set by board_init_f().
 *
 * 6. For U-Boot proper (not SPL), some CPUs have some work left to do
 *    at this point regarding memory, so call c_runtime_cpu_setup.
 *
 * 7. Branch to board_init_r().
 *
 * For more information see 'Board Initialisation Flow in README.
 */

/*
 * entry point of crt0 sequence
 */

ENTRY(_main)

/*
 * Set up initial C runtime environment and call board_init_f(0).
 */

#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
    ldr sp, =(CONFIG_SPL_STACK)
#else
    ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
#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
    mov r0, sp
    bl  board_init_f_mem
    mov sp, r0

    mov r0, #0
    bl  board_init_f

#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
# 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 */
    ldr pc, =board_init_r   /* this is auto-relocated! */

    /* we should not return here. */
#endif

ENDPROC(_main)

这个段汇编主要作用是:
(1)初始化一个C语言能够运行的环境
(2)bl board_init_f 该函数在 u-boot-2016.01/Common/Board_f.c 中,初始化串口等,有一个初始化列表 其中有一个和我们具体板载有关的函数board_early_init_f 该函数在 u-boot-2016.01/board/samsung/smdk2410.c 用C语言初始化了时钟和GPIO口等,完全可以自己重新编写
(3)设置堆栈地址
(4)设置全局变量gd结构体
(5)中断向量表的重映射
(6)未初始化段(bss)的清除
(7)最后调用ldr pc, =board_init_r 该函数在 u-boot-2016.01/Common/Board_r.c 中,该函数也有一个初始化列表其中有一个是和我们具体板载有关的初始化函数 board_init 该函数在 u-boot-2016.01/board/samsung/smdk2410.c 中,主要设置将来和Linux内核比较的机器码同时打开了icache和dcache。在这个初始化列表的最后条用了run_main_loop 该函数就在u-boot-2016.01/Common/Board_r.c 其中又调用了main_loop(); 该函数在 u-boot-2016.01/Common/Main.c中,函数main_loop();最后调用u-boot中的bootargs来引导Linux内核。

注:一直到这里u-boot的使命完成。
总结主要用到的文件路径:

u-boot-2016.01/arch/arm/lib/vectors .S 
u-boot-2016-01/arch/arm/cpu/arm920t/start.S
u-boot-2016.01/arch/arm/lib/crt0.S 
u-boot-2016.01/Common/Board_f.c
u-boot-2016.01/Common/Board_r.c
u-boot-2016.01/board/samsung/smdk2410.c
u-boot-2016.01/Common/Main.c

另外:在u-boot-2015.10以后在u-boot.xx/arch/arm/lib/ 下面就没有board.c这个文件了。

最后查看一下:u-boot-2016.01/arch/arm/cpu/s3c24x0/ 路径下的几个文件:

Cup_info.c
Interrupts.c
Makefile
Speed.c
Time.c
这几个文件的具体实现很重要。

所需要的头文件都定义在如下文件下面:

u-boot-2016.01/arch/arm/Include/asm/Arch-s3c24x0/

备注:以上简单分析主要是为了自己下面移植s3c2416做的前期工作。文章还缺少一些注释等有机会在写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值