uboot2010.06 transplant from NOR flash start analysis

Source: Internet
Author: User

Program from start. s start start

Start_code:
/*
* Set the CPU to SVC32 mode settings management mode
*/
Mrs R0, CPSR
Bic R0, R0, #0x1f
Orr R0, R0, #0xd3
MSR CPSR, R0

#ifdef config_s3c24x0
/* Turn off the watchdog */

/* off watchdog off interrupt */

# if defined (config_s3c2400)
# define Pwtcon 0x15300000
# define INTMSK 0x14400008/* Interupt-controller Base addresses * *
# define CLKDIVN 0x14800014 */clock divisor register */
#else
# define Pwtcon 0x53000000
# define INTMSK 0x4a000008/* Interupt-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)//shut up all interrupt
LDR R1, =0X3FF
Ldr R0, =intsubmsk
STR R1, [R0]
# endif

/* FCLK:HCLK:PCLK = 1:2:4 */
/* Default FCLK is to + MHz! */
Ldr R0, =CLKDIVN
mov r1, #3
STR R1, [R0]
#endif/* config_s3c24x0 */

#ifndef Config_skip_lowlevel_init
BL Cpu_init_crit #跳转到cpu_init_crit处 Initialize the CPU Cashe MMU off
#endif

#ifndef config_skip_relocate_uboot
relocate:    /* relocate u-boot to RAM      * * #加载uboot到RAM对于nor Flash startup boot//can run directly but is inefficient so load into RAM to run
 adr r0, _start  /* R0 <-Current position of code   */   #加载运行起始地址到r0   If starting from nor flash here is 0x0
 ldr  R1, _text_base  /* Test if we run from flash or RAM */#加载_TEXT_BASE到r1 _text_base in SDRAM    default to 0X33F80
 cmp r0, r1   /* don ' t reloc during debug          */      #比较r0 and R1 to determine whether the program starts from Flash or starts from Ram
 beq stack_setup   /* if R0 = = R1 jumps to stack_up*/         #如果相等 means boot from RAM then the following code moves to the RAM step. Jump directly to Stack_setup run

 ldr r2, _armboot_start           #代码搬运
  LDR&NBSP;R3, _bss_start      /*u-boot.lds defines the end address of the Uboot code */
&NBSP;SUB&NBSP;R2, R3, r2  /* R2 <-size of armboot            */    #得到代码长度
 add r2, r0, r2  /* R2 <-source End address    & nbsp;    */  #r2中存放uboot结束代码地址

Copy_loop:/* Move data from Norflash to SDRAM R0 to _start program start address R1 to _text_base belongs to the address in SDRAM 0x33f80000 so our uboot 512kb*/
Ldmia r0!, {r3-r10}/* Copy from source address [r0] */#从起始地址开始搬_start
Stmia r1!, {r3-r10}/* Copy to target address [R1]/#搬到目的地址 starting from _text_base
CMP r0, r2/* until source end ADDREEE [R2]/#判断是否搬完 that is, the value in r0 is = = above R2 middle value
Ble copy_loop
#endif/* Config_skip_relocate_uboot */

/* Set up the stack */
Stack_setup: #搬完了后设置栈 said before the judging program start address if you start from RAM directly to set up the stack, there is a stack to use the C language ...
LDR R0, _text_base/* Upper kib:relocated Uboot * * #栈为向下生长 set aside some space before determining the stack pointer sp
Sub R0, R0, #CONFIG_SYS_MALLOC_LEN/* malloc area */#1 length of the malloc segment
Sub R0, R0, #CONFIG_SYS_GBL_DATA_SIZE/* bdinfo * * #2 a length of time to place GBL segments
#ifdef CONFIG_USE_IRQ
Sub R0, R0, # (Config_stacksize_irq+config_stacksize_fiq) #3 also leave a length of time to place the IRQ FIQ Interrupt State Save segment
#endif
Sub sp, R0, #12/* Leave 3 words for abort-stack */
Bic sp, SP, #7/* 8-byte alignment for ABI compliance */#接下来就是sp指针的位置了

CLEAR_BSS: #做完了后在开始跳到uboot第二 Phase C code cleared BSS This puts a number of global # variables initialized to 0 or uninitialized local variables can be cleared before being assigned when they are called.
LDR R0, _bss_start/* Find start of BSS segment */
LDR R1, _bss_end/* stop here */
mov r2, #0x00000000/* Clear */#全部清空

Clbss_l:str R2, [r0]/* Clear loop ... */
Add R0, R0, #4
CMP R0, R1
Ble clbss_l

Ldr pc, _start_armboot #将指针指向_start_armboot Here's the entrance to the second-stage C function.

_start_armboot:. Word start_armboot

void Start_armboot (void)
{
init_fnc_t **init_fnc_ptr;
Char *s;
#if defined (config_vfd) | | Defined (CONFIG_LCD)
unsigned long addr;
#endif

/* Pointer is writable since we allocated a register for it */
GD = (gd_t*) (_armboot_start-config_sys_malloc_len-sizeof (gd_t));
/* Compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__ (""::: "Memory");

memset ((void*) GD, 0, sizeof (gd_t));
GD->BD = (bd_t*) ((char*) gd-sizeof (bd_t));
memset (gd->bd, 0, sizeof (bd_t));

Gd->flags |= Gd_flg_reloc;

Monitor_flash_len = _bss_start-_armboot_start;

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {//Here for the invocation of a series of initialization functions specifically see Uboot Source code, is the first The serial port of each peripheral module is started. GPIO USB
if ((*INIT_FNC_PTR) ()! = 0) {
Hang ();
}
}

/* Armboot_start is defined in the BOARD-SPECIFIC linker script */
Mem_malloc_init (_armboot_start-config_sys_malloc_len,
Config_sys_malloc_len);

#ifndef Config_sys_no_flash
/* Configure available FLASH banks */
Display_flash_config (Flash_init ());
#endif/* Config_sys_no_flash */

#ifdef CONFIG_VFD
# ifndef Page_size
# define Page_size 4096
# endif
/*
* Reserve Memory for VFD display (always full pages)
*/
/* Bss_end is defined in the BOARD-SPECIFIC linker script */
Addr = (_bss_end + (page_size-1)) & ~ (page_size-1);
Vfd_setmem (addr);
Gd->fb_base = addr;
#endif/* CONFIG_VFD */

#ifdef CONFIG_LCD
/* Board Init may have inited fb_base */
if (!gd->fb_base) {
# ifndef Page_size
# define Page_size 4096
# endif
/*
* Reserve Memory for LCD display (always full pages)
*/
/* Bss_end is defined in the BOARD-SPECIFIC linker script */
Addr = (_bss_end + (page_size-1)) & ~ (page_size-1);
Lcd_setmem (addr);
Gd->fb_base = addr;
}
#endif/* CONFIG_LCD */

#if defined (Config_cmd_nand)
Puts ("NAND:");
Nand_init (); /* Go init the NAND */
#endif

#if defined (Config_cmd_onenand)
Onenand_init ();
#endif

#ifdef Config_has_dataflash
At91f_dataflashinit ();
Dataflash_print_info ();
#endif

/* Initialize Environment */
Env_relocate ();

#ifdef CONFIG_VFD
/* Must do this after the framebuffer is allocated */
Drv_vfd_init ();
#endif/* CONFIG_VFD */

#ifdef Config_serial_multi
Serial_initialize ();
#endif

/* IP Address */
GD->BD->BI_IP_ADDR = getenv_ipaddr ("ipaddr");

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 */

#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

/* Enable exceptions */
Enable_interrupts ();

/* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_TI_EMAC
/* Xxx:this needs to being moved to board INIT */
extern void Davinci_eth_set_mac_addr (const u_int8_t *ADDR);
if (getenv ("ethaddr")) {
Uchar Enetaddr[6];
ETH_GETENV_ENETADDR ("Ethaddr", enetaddr);
DAVINCI_ETH_SET_MAC_ADDR (ENETADDR);
}
#endif

#if defined (config_driver_smc91111) | | Defined (config_driver_lan91c96)
/* Xxx:this needs to being moved to board INIT */
if (getenv ("ethaddr")) {
Uchar Enetaddr[6];
ETH_GETENV_ENETADDR ("Ethaddr", enetaddr);
SMC_SET_MAC_ADDR (ENETADDR);
}
#endif/* config_driver_smc91111 | | CONFIG_DRIVER_LAN91C96 * *

/* Initialize from Environment */
if ((s = getenv ("loadaddr"))! = NULL) {
LOAD_ADDR = Simple_strtoul (S, NULL, 16);
}
#if defined (config_cmd_net)
if ((s = getenv ("Bootfile"))! = NULL) {
Copy_filename (Bootfile, S, sizeof (Bootfile));
}
#endif

#ifdef Board_late_init
Board_late_init ();
#endif

#ifdef CONFIG_GENERIC_MMC
Puts ("MMC:");
Mmc_initialize (GD->BD);
#endif

#ifdef CONFIG_BITBANGMII
Bb_miiphy_init ();
#endif
#if defined (config_cmd_net)
#if defined (CONFIG_NET_MULTI)
Puts ("Net:");
#endif
Eth_initialize (GD->BD);
#if defined (config_reset_phy_r)
Debug ("Reset Ethernet phy\n");
Reset_phy ();
#endif
#endif
/* Main_loop () can return to retry autoboot, if so just run it again. */
for (;;) {
Main_loop (); After initialization of each board level peripheral is completed, enter Main_loop () dead loop
}

/* Notreached-no-out-of-command loop except booting */
}

void Main_loop (void)

s = getenv ("BootDelay");
BootDelay = s?        (int) Simple_strtol (s, NULL, ten): Config_bootdelay; If you define a delay load this article deals with an important function getenv () Get environment variables

Run_command (s, 0); Running command functions in a dead loop we enter various commands on the serial port by this function to parse

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.