S5P4418 uboot 分析

瘋耔新浪微博:   http://weibo.com/cpjphone

一:

1◑ 从链接脚本文件u-boot.lds('/opt/4418-source/android/u-boot' )中可以找到代码的起始:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_stext)
SECTIONS
{
. = 0x00000000;
. = ALIGN();
.text :
{
*(.__image_copy_start)
arch/arm/cpu/slsiap/s5p4418/start.o (.text*)
*(.text*)
}

从中知道程序的入口点是_start,定位于arch/arm/cpu/slsiap/s5p4418/start.o (即u-boot启动的第一阶段)。

▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒

2◑ 下面我们来仔细分析一下 start.S。(请对照数据手册阅读源码):

/*
* armboot - Startup Code for NXPxxxx/ARM Cortex CPU-core
*/ #include <asm-offsets.h>
#include <config.h>
#include <version.h>
#include <asm/system.h>
#include <linux/linkage.h> /*
*************************************************************************
*
* Exception vectors as described in ARM reference manuals
*
* replace arm/lib/vectors.S
*
*************************************************************************
*/
.globl _stext
_stext:
b reset //u-boot的主入口,跳入了后面的reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt //这些是跳转向量表,和芯片的体系结构有关
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used // ldr语句的意思是将第二个操作数(如:_undefined_instruction)指向的地址数据传给PC
ldr pc, _irq
ldr pc, _fiq /* ldr语句的意思是将第二个操作数(如:_undefined_instruction)指向的地址数据传给PC,undefined_instruction 为地址, 即后面标号所对的偏移地址数据 */
_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 ,0xdeadbeef //16字节对齐,并以0xdeadbeef填充,它是个Magic number。 /*
*************************************************************************
*
* Text and section base
*
*************************************************************************
*/ .globl TEXT_BASE
TEXT_BASE:
.word CONFIG_SYS_TEXT_BASE //这些和上面的一样,定义一个4字节的空间存放地址 /*
* These are defined in the board-specific linker script.
*/
.globl _bss_start_ofs
_bss_start_ofs:
.word __bss_start - _stext .globl _bss_end_ofs
_bss_end_ofs:
.word __bss_end - _stext .globl _end_ofs
_end_ofs:
.word _end - _stext /*
*************************************************************************
*
* Reset handling 代码从这里开始执行
*
*************************************************************************
*/ .globl reset reset:
bl save_boot_params
/*
* set the cpu to SVC32 mode 让系统进入SVC(管理)员
*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0 /* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15
bl cpu_init_crit
#endif #ifdef CONFIG_RELOC_TO_TEXT_BASE
relocate_to_text:
/*
* relocate u-boot code on memory to text base
* for nexell arm core (add by jhkim)
*/
adr r0, _stext /* 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 clear_bss ldr r2, _bss_start_ofs
add r2, r0, r2 /* r2 <- source end address */ copy_loop_text:
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_text ldr r1, TEXT_BASE /* restart at text base */
mov pc, r1 clear_bss:
ldr r0, _bss_start_ofs
ldr r1, _bss_end_ofs
ldr r4, TEXT_BASE /* text addr */
add r0, r0, r4
add r1, r1, r4
mov r2, #0x00000000 /* clear */ clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #
cmp r0, r1
bne clbss_l #ifdef CONFIG_MMU_ENABLE
bl mmu_turn_on
#endif ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, # /* 8-byte alignment for ABI compliance */
sub sp, #GD_SIZE /* allocate one GD above SP */
bic sp, sp, # /* 8-byte alignment for ABI compliance */
mov r9, sp /* GD is above SP */
mov r0, #
bl board_init_f mov sp, r9 /* SP is GD's base address */
bic sp, sp, # /* 8-byte alignment for ABI compliance */
sub sp, #GENERATED_BD_INFO_SIZE /* allocate one BD above SP */
bic sp, sp, # /* 8-byte alignment for ABI compliance */ mov r0, r9 /* gd_t *gd */
ldr r1, TEXT_BASE /* ulong text */
mov r2, sp /* ulong sp */
bl gdt_reset /* call board_init_r(gd_t *id, ulong dest_addr) */
mov r0, r9 /* gd_t */
ldr r1, =(CONFIG_SYS_MALLOC_END) /* dest_addr for malloc heap end */
/* call board_init_r */
ldr pc, =board_init_r /* this is auto-relocated! */ #else /* CONFIG_RELOC_TO_TEXT_BASE */ bl _main
#endif /*------------------------------------------------------------------------------*/ ENTRY(c_runtime_cpu_setup)
/*
* If I-cache is enabled invalidate it
*/
#ifndef CONFIG_SYS_ICACHE_OFF
mcr p15, , r0, c7, c5, @ invalidate icache
mcr p15, , r0, c7, c10, @ DSB
mcr p15, , r0, c7, c5, @ ISB
#endif
/*
* Move vector table
*/
/* Set vector address in CP15 VBAR register */
ldr r0, =_stext
mcr p15, , r0, c12, c0, @Set VBAR bx lr ENDPROC(c_runtime_cpu_setup) /*************************************************************************
*
* void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
* __attribute__((weak));
*
* Stack pointer is not yet initialized at this moment
* Don't save anything to stack even if compiled with -O0
*
*************************************************************************/
ENTRY(save_boot_params)
bx lr @ back to my caller
ENDPROC(save_boot_params)
.weak save_boot_params /*************************************************************************
*
* cpu_init_cp15
*
* Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
* CONFIG_SYS_ICACHE_OFF is defined.
* 操作CP15协处理器
*
*************************************************************************/
ENTRY(cpu_init_cp15)
/*
* Invalidate L1 I/D
*/
mov r0, # @ set up for MCR
mcr p15, , r0, c8, c7, @ invalidate TLBs
mcr p15, , r0, c7, c5, @ invalidate icache
mcr p15, , r0, c7, c5, @ invalidate BP array dsb
isb /*
* disable MMU stuff and caches
*下面主要是中断相关代码,但是U-boot基本不使用中断所以暂且略过。
*/
mrc p15, , r0, c1, c0,
bic r0, r0, #0x00002000 @ clear bits (--V-)
bic r0, r0, #0x00000007 @ clear bits : (-CAM)
orr r0, r0, #0x00000002 @ set bit (--A-) Align
orr r0, r0, #0x00000800 @ set bit (Z---) BTB
#ifdef CONFIG_SYS_ICACHE_OFF
bic r0, r0, #0x00001000 @ clear bit (I) I-cache
#else
orr r0, r0, #0x00001000 @ set bit (I) I-cache
#endif
mcr p15, , r0, c1, c0,
mov pc, lr @ back to my caller
ENDPROC(cpu_init_cp15) #ifndef CONFIG_SKIP_LOWLEVEL_INIT
/*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************/
ENTRY(cpu_init_crit)
/*
* Jump to board specific initialization...
* The Mask ROM will have already initialized
* basic memory. Go here to bump up clock rate and handle
* wake up conditions.
*/
/* 调用board/lowlevel_init.S中的lowlevel_init函数,对系统总线的初始化,初始化了连接存储器的位宽、速度、刷新率等重要参数。经过这个函数的正确初始化,Nor Flash、SDRAM才可以被系统使用。
*/
b lowlevel_init @ go setup pll,mux,memory
ENDPROC(cpu_init_crit)
#endif

▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒

3◑现在我们再来看看lib/arm/board.c中的第二阶段入口函数board_init_r:

/*
* (C) Copyright 2002-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2002
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
* Marius Groeger <mgroeger@sysgo.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/ /*
* To match the U-Boot user interface on ARM platforms to the U-Boot
* standard (as on PPC platforms), some messages with debug character
* are removed from the default U-Boot build.
*
* Define DEBUG here if you want additional info as shown below
* printed upon startup:
*
* U-Boot code: 00F00000 -> 00F3C774 BSS: -> 00FC3274
* IRQ Stack: 00ebff7c
* FIQ Stack: 00ebef7c
*/ #include <common.h>
#include <command.h>
#include <environment.h>
#include <malloc.h>
#include <stdio_dev.h>
#include <version.h>
#include <net.h>
#include <serial.h>
#include <nand.h>
#include <onenand_uboot.h>
#include <mmc.h>
#include <scsi.h>
#include <libfdt.h>
#include <fdtdec.h>
#include <post.h>
#include <logbuff.h>
#include <asm/sections.h> #ifdef CONFIG_BITBANGMII
#include <miiphy.h>
#endif DECLARE_GLOBAL_DATA_PTR; ulong monitor_flash_len; #ifdef CONFIG_HAS_DATAFLASH
extern int AT91F_DataflashInit(void);
extern void dataflash_print_info(void);
#endif #if defined(CONFIG_HARD_I2C) || \
defined(CONFIG_SYS_I2C)
#include <i2c.h>
#endif /************************************************************************
* Coloured LED functionality
************************************************************************
* May be supplied by boards if desired
*/
inline void __coloured_LED_init(void) {}
void coloured_LED_init(void)
__attribute__((weak, alias("__coloured_LED_init")));
inline void __red_led_on(void) {}
void red_led_on(void) __attribute__((weak, alias("__red_led_on")));
inline void __red_led_off(void) {}
void red_led_off(void) __attribute__((weak, alias("__red_led_off")));
inline void __green_led_on(void) {}
void green_led_on(void) __attribute__((weak, alias("__green_led_on")));
inline void __green_led_off(void) {}
void green_led_off(void) __attribute__((weak, alias("__green_led_off")));
inline void __yellow_led_on(void) {}
void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on")));
inline void __yellow_led_off(void) {}
void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off")));
inline void __blue_led_on(void) {}
void blue_led_on(void) __attribute__((weak, alias("__blue_led_on")));
inline void __blue_led_off(void) {}
void blue_led_off(void) __attribute__((weak, alias("__blue_led_off"))); /*
************************************************************************
* Init Utilities *
************************************************************************
* Some of this code should be moved into the core functions,
* or dropped completely,
* but let's get it working (again) first...
*/ #if defined(CONFIG_ARM_DCC) && !defined(CONFIG_BAUDRATE)
#define CONFIG_BAUDRATE 115200
#endif static int init_baudrate(void)
{
gd->baudrate = getenv_ulong("baudrate", , CONFIG_BAUDRATE);
return ;
} static int display_banner(void)
{
printf("\n\n%s\n\n", version_string);
debug("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
(ulong)&_start,
(ulong)&__bss_start, (ulong)&__bss_end);
#ifdef CONFIG_MODEM_SUPPORT
debug("Modem Support enabled\n");
#endif
#ifdef CONFIG_USE_IRQ
debug("IRQ Stack: %08lx\n", IRQ_STACK_START);
debug("FIQ Stack: %08lx\n", FIQ_STACK_START);
#endif return ();
} /*
* WARNING: this code looks "cleaner" than the PowerPC version, but
* has the disadvantage that you either get nothing, or everything.
* On PowerPC, you might see "DRAM: " before the system hangs - which
* gives a simple yet clear indication which part of the
* initialization if failing.
*/
static int display_dram_config(void)
{
int i; #ifdef DEBUG
puts("RAM Configuration:\n"); for (i = ; i < CONFIG_NR_DRAM_BANKS; i++) {
printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
print_size(gd->bd->bi_dram[i].size, "\n");
}
#else
ulong size = ; for (i = ; i < CONFIG_NR_DRAM_BANKS; i++)
size += gd->bd->bi_dram[i].size; puts("DRAM: ");
print_size(size, "\n");
#endif return ();
} #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
static int init_func_i2c(void)
{
puts("I2C: ");
#ifdef CONFIG_SYS_I2C
i2c_init_all();
#else
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
puts("ready\n");
return ();
}
#endif #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
#include <pci.h>
static int arm_pci_init(void)
{
pci_init();
return ;
}
#endif /* CONFIG_CMD_PCI || CONFIG_PCI */ /*
* Breathe some life into the board...
*
* Initialize a serial port as console, and carry out some hardware
* tests.
*
* The first part of initialization is running from Flash memory;
* its main purpose is to initialize the RAM so that we
* can relocate the monitor code to RAM.
*/ /*
* All attempts to come up with a "common" initialization sequence
* that works for all boards and architectures failed: some of the
* requirements are just _too_ different. To get rid of the resulting
* mess of board dependent #ifdef'ed code we now make the whole
* initialization sequence configurable to the user.
*
* The requirements for any new initalization function is simple: it
* receives a pointer to the "global data" structure as it's only
* argument, and returns an integer return code, where 0 means
* "continue" and != 0 means "fatal error, hang the system".
*/
typedef int (init_fnc_t) (void); void __dram_init_banksize(void)
{
gd->bd->bi_dram[].start = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_dram[].size = gd->ram_size;
}
void dram_init_banksize(void)
__attribute__((weak, alias("__dram_init_banksize"))); int __arch_cpu_init(void)
{
return ;
}
int arch_cpu_init(void)
__attribute__((weak, alias("__arch_cpu_init"))); int __power_init_board(void)
{
return ;
}
int power_init_board(void)
__attribute__((weak, alias("__power_init_board"))); /* Record the board_init_f() bootstage (after arch_cpu_init()) */
static int mark_bootstage(void)
{
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f"); return ;
} init_fnc_t *init_sequence[] = {
arch_cpu_init, /* basic arch cpu dependent setup */
mark_bootstage,
#ifdef CONFIG_OF_CONTROL
fdtdec_check_fdt,
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
timer_init, /* initialize timer */
#ifdef CONFIG_BOARD_POSTCLK_INIT
board_postclk_init,
#endif
#ifdef CONFIG_FSL_ESDHC
get_clocks,
#endif
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
print_cpuinfo, /* display cpu info (and speed) */
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
init_func_i2c,
#endif
dram_init, /* configure available RAM banks */
NULL,
}; void board_init_f(ulong bootflag)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
gd_t *id;
ulong addr, addr_sp;
#ifdef CONFIG_PRAM
ulong reg;
#endif
void *new_fdt = NULL;
size_t fdt_size = ; memset((void *)gd, , sizeof(gd_t)); gd->mon_len = (ulong)&__bss_end - (ulong)_start;
#ifdef CONFIG_OF_EMBED
/* Get a pointer to the FDT */
gd->fdt_blob = __dtb_dt_begin;
#elif defined CONFIG_OF_SEPARATE
/* FDT is at end of image */
gd->fdt_blob = &_end;
#endif
/* Allow the early environment to override the fdt address */
gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", ,
(uintptr_t)gd->fdt_blob); for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != ) {
hang ();
}
} #ifdef CONFIG_OF_CONTROL
/* For now, put this check after the console is ready */
if (fdtdec_prepare_fdt()) {
panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
"doc/README.fdt-control");
}
#endif debug("monitor len: %08lX\n", gd->mon_len);
/*
* Ram is setup, size stored in gd !!
*/
debug("ramsize: %08lX\n", gd->ram_size);
#if defined(CONFIG_SYS_MEM_TOP_HIDE)
/*
* Subtract specified amount of memory to hide so that it won't
* get "touched" at all by U-Boot. By fixing up gd->ram_size
* the Linux kernel should now get passed the now "corrected"
* memory size and won't touch it either. This should work
* for arch/ppc and arch/powerpc. Only Linux board ports in
* arch/powerpc with bootwrapper support, that recalculate the
* memory size from the SDRAM controller setup will have to
* get fixed.
*/
gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
#endif addr = CONFIG_SYS_SDRAM_BASE + get_effective_memsize(); #ifdef CONFIG_LOGBUFFER
#ifndef CONFIG_ALT_LB_ADDR
/* reserve kernel log buffer */
addr -= (LOGBUFF_RESERVE);
debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
addr);
#endif
#endif #ifdef CONFIG_PRAM
/*
* reserve protected RAM
*/
reg = getenv_ulong("pram", , CONFIG_PRAM);
addr -= (reg << ); /* size is in kB */
debug("Reserving %ldk for protected RAM at %08lx\n", reg, addr);
#endif /* CONFIG_PRAM */ #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
/* reserve TLB table */
gd->arch.tlb_size = PGTABLE_SIZE;
addr -= gd->arch.tlb_size; /* round down to next 64 kB limit */
addr &= ~(0x10000 - ); gd->arch.tlb_addr = addr;
debug("TLB table from %08lx to %08lx\n", addr, addr + gd->arch.tlb_size);
#endif /* round down to next 4 kB limit */
addr &= ~( - );
debug("Top of RAM usable for U-Boot at: %08lx\n", addr); #ifdef CONFIG_LCD
#ifdef CONFIG_FB_ADDR
gd->fb_base = CONFIG_FB_ADDR;
#else
/* reserve memory for LCD display (always full pages) */
addr = lcd_setmem(addr);
gd->fb_base = addr;
#endif /* CONFIG_FB_ADDR */
#endif /* CONFIG_LCD */ /*
* reserve memory for U-Boot code, data & bss
* round down to next 4 kB limit
*/
addr -= gd->mon_len;
addr &= ~( - ); debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> , addr); #ifndef CONFIG_SPL_BUILD
/*
* reserve memory for malloc() arena
*/
addr_sp = addr - TOTAL_MALLOC_LEN;
debug("Reserving %dk for malloc() at: %08lx\n",
TOTAL_MALLOC_LEN >> , addr_sp);
/*
* (permanently) allocate a Board Info struct
* and a permanent copy of the "global" data
*/
addr_sp -= sizeof (bd_t);
bd = (bd_t *) addr_sp;
gd->bd = bd;
debug("Reserving %zu Bytes for Board Info at: %08lx\n",
sizeof (bd_t), addr_sp); #ifdef CONFIG_MACH_TYPE
gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
#endif addr_sp -= sizeof (gd_t);
id = (gd_t *) addr_sp;
debug("Reserving %zu Bytes for Global Data at: %08lx\n",
sizeof (gd_t), addr_sp); #if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL)
/*
* If the device tree is sitting immediate above our image then we
* must relocate it. If it is embedded in the data section, then it
* will be relocated with other data.
*/
if (gd->fdt_blob) {
fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, ); addr_sp -= fdt_size;
new_fdt = (void *)addr_sp;
debug("Reserving %zu Bytes for FDT at: %08lx\n",
fdt_size, addr_sp);
}
#endif #ifndef CONFIG_ARM64
/* setup stackpointer for exeptions */
gd->irq_sp = addr_sp;
#ifdef CONFIG_USE_IRQ
addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp);
#endif
/* leave 3 words for abort-stack */
addr_sp -= ; /* 8-byte alignment for ABI compliance */
addr_sp &= ~0x07;
#else /* CONFIG_ARM64 */
/* 16-byte alignment for ABI compliance */
addr_sp &= ~0x0f;
#endif /* CONFIG_ARM64 */
#else
addr_sp += ; /* leave 32 words for abort-stack */
gd->irq_sp = addr_sp;
#endif debug("New Stack Pointer is: %08lx\n", addr_sp); #ifdef CONFIG_POST
post_bootmode_init();
post_run(NULL, POST_ROM | post_bootmode_get());
#endif /* Ram ist board specific, so move it to board code ... */
dram_init_banksize();
display_dram_config(); /* and display it */ gd->relocaddr = addr;
gd->start_addr_sp = addr_sp;
gd->reloc_off = addr - (ulong)&_start;
debug("relocation Offset is: %08lx\n", gd->reloc_off);
if (new_fdt) {
memcpy(new_fdt, gd->fdt_blob, fdt_size);
gd->fdt_blob = new_fdt;
}
memcpy(id, (void *)gd, sizeof(gd_t));
} #if !defined(CONFIG_SYS_NO_FLASH)
static char *failed = "*** failed ***\n";
#endif /*
* Tell if it's OK to load the environment early in boot.
*
* If CONFIG_OF_CONFIG is defined, we'll check with the FDT to see
* if this is OK (defaulting to saying it's not OK).
*
* NOTE: Loading the environment early can be a bad idea if security is
* important, since no verification is done on the environment.
*
* @return 0 if environment should not be loaded, !=0 if it is ok to load
*/
static int should_load_env(void)
{
#ifdef CONFIG_OF_CONTROL
return fdtdec_get_config_int(gd->fdt_blob, "load-environment", );
#elif defined CONFIG_DELAY_ENVIRONMENT
return ;
#else
return ;
#endif
} #if defined(CONFIG_DISPLAY_BOARDINFO_LATE) && defined(CONFIG_OF_CONTROL)
static void display_fdt_model(const void *blob)
{
const char *model; model = (char *)fdt_getprop(blob, , "model", NULL);
printf("Model: %s\n", model ? model : "<unknown>");
}
#endif /************************************************************************
*
* This is the next part if the initialization sequence: we are now
* running from RAM and have a "normal" C environment, i. e. global
* data can be written, BSS has been cleared, the stack size in not
* that critical any more, etc.
*
************************************************************************
*/ void board_init_r(gd_t *id, ulong dest_addr)
{
ulong malloc_start;
#if !defined(CONFIG_SYS_NO_FLASH)
ulong flash_size;
#endif gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); monitor_flash_len = (ulong)&__rel_dyn_end - (ulong)_start; /* Enable caches */
enable_caches(); debug("monitor flash len: %08lX\n", monitor_flash_len);
board_init(); /* Setup chipselects */
/*
* TODO: printing of the clock inforamtion of the board is now
* implemented as part of bdinfo command. Currently only support for
* davinci SOC's is added. Remove this check once all the board
* implement this.
*/
#ifdef CONFIG_CLOCKS
set_cpu_clk_info(); /* Setup clock information */
#endif
serial_initialize(); debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr); #ifdef CONFIG_LOGBUFFER
logbuff_init_ptrs();
#endif
#ifdef CONFIG_POST
post_output_backlog();
#endif /* The Malloc area is immediately below the monitor copy in DRAM */
malloc_start = dest_addr - TOTAL_MALLOC_LEN;
mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN); #ifdef CONFIG_ARCH_EARLY_INIT_R
arch_early_init_r();
#endif #ifndef CONFIG_PMIC_REG_DUMP
power_init_board();
#endif #if !defined(CONFIG_SYS_NO_FLASH)
puts("Flash: "); flash_size = flash_init();
if (flash_size > ) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
print_size(flash_size, "");
/*
* Compute and print flash CRC if flashchecksum is set to 'y'
*
* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
*/
if (getenv_yesno("flashchecksum") == ) {
printf(" CRC: %08X", crc32(,
(const unsigned char *) CONFIG_SYS_FLASH_BASE,
flash_size));
}
putc('\n');
# else /* !CONFIG_SYS_FLASH_CHECKSUM */
print_size(flash_size, "\n");
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
} else {
puts(failed);
hang();
}
#endif #if defined(CONFIG_CMD_NAND)
#if defined(CONFIG_NAND_MTD)
puts("NAND: ");
nand_init(); /* go init the NAND */
#elif defined(CONFIG_NAND_FTL)
#include <nand_ftl.h>
puts("NAND FTL: ");
nand_ftl_init(); /* go init the NAND */
#endif
#endif /* CONFIG_CMD_NAND */ #if defined(CONFIG_CMD_ONENAND)
onenand_init();
#endif #ifdef CONFIG_GENERIC_MMC
puts("MMC: ");
mmc_initialize(gd->bd);
#endif #ifdef CONFIG_CMD_SCSI
puts("SCSI: ");
scsi_init();
#endif #ifdef CONFIG_HAS_DATAFLASH
AT91F_DataflashInit();
dataflash_print_info();
#endif /* initialize environment */
if (should_load_env())
env_relocate();
else
set_default_env(NULL); #if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
arm_pci_init();
#endif stdio_init(); /* get the devices list going. */ jumptable_init(); #if defined(CONFIG_API)
/* Initialize API */
api_init();
#endif console_init_r(); /* fully init console as a device */ #ifdef CONFIG_PMIC_REG_DUMP
power_init_board();
#endif #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
# ifdef CONFIG_OF_CONTROL
/* Put this here so it appears on the LCD, now it is ready */
display_fdt_model(gd->fdt_blob);
# else
checkboard();
# endif
#endif #if defined(CONFIG_ARCH_MISC_INIT)
/* miscellaneous arch dependent initialisations */
arch_misc_init();
#endif
#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r();
#endif /* set up exceptions */
interrupt_init();
/* enable exceptions */
enable_interrupts(); /* Initialize from environment */
load_addr = getenv_ulong("loadaddr", , load_addr); #ifdef CONFIG_BOARD_LATE_INIT
board_late_init();
#endif #ifdef CONFIG_BITBANGMII
bb_miiphy_init();
#endif
#if defined(CONFIG_CMD_NET)
puts("Net: ");
eth_initialize(gd->bd);
#if defined(CONFIG_RESET_PHY_R)
debug("Reset Ethernet PHY\n");
reset_phy();
#endif
#endif #ifdef CONFIG_POST
post_run(NULL, POST_RAM | post_bootmode_get());
#endif #if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
/*
* Export available size of memory for Linux,
* taking into account the protected RAM at top of memory
*/
{
ulong pram = ;
uchar memsz[]; #ifdef CONFIG_PRAM
pram = getenv_ulong("pram", , CONFIG_PRAM);
#endif
#ifdef CONFIG_LOGBUFFER
#ifndef CONFIG_ALT_LB_ADDR
/* Also take the logbuffer into account (pram is in kB) */
pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / ;
#endif
#endif
sprintf((char *)memsz, "%ldk", (gd->ram_size / ) - pram);
setenv("mem", (char *)memsz);
}
#endif /* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop();
}
/*
进入主循环,其中会读取bootdelay和bootcmd 在bootdelay时间内按下键进入命令行,否则执行bootcmd的命令。
*/
/* NOTREACHED - no way out of command loop except booting */
}

希望网友积极留言,共同完成4418资料集

-----------------------------

上一篇:HTML5 CSS3 诱人的实例: 3D立方体旋转动画


下一篇:.Net项目版本号的生成